博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Node.js 线程你理解的可能是错的
阅读量:5789 次
发布时间:2019-06-18

本文共 2219 字,大约阅读时间需要 7 分钟。

本文代码运行环境系统:MacOS High SierraNode.js:10.3.0

Node.js是单线程的,那么Node.js启动后线程数是1?

答案:Node.js启动后线程数并不是1,以下面代码为例

const http = require('http');http.createServer((req, res) => {    res.end('hello');}).listen(8000, () => {  console.log('server is listening: ' + 8000);});

通过Mac实用工具 > 活动监视器可以查看进程的线程数其实是6

Node.js启动的线程数不为1,是因为线程池?

答案:线程数不为1,不是因为线程池,而是因为V8。Node.js启动后会创建V8实例,V8实例是多线程的,V8中的线程有:

  • 主线程:获取代码、编译执行
  • 编译线程:主线程执行的时候,可以优化代码
  • Profiler线程:记录哪些方法耗时,为优化提供支持
  • 其他线程:用于垃圾回收清除工作,因为是多个线程,所以可以并行清除

Node.js线程池是预先创建好的?

答案:并不是,线程池中的线程是按需创建的。

const http = require('http');const fs = require('fs');http.createServer((req, res) => {  fs.readFile('./c.js', () => {});  res.end('hello');}).listen(8000, () => {  console.log('server is listening: ' + 8000);});

上面代码启动后,线程数依然是6

通过ab模拟访问后

ab -n1000 -c20 'http://192.168.76.101:8000/'

线程数才变成了10。之所以为10,是因为线程池中线程的默认值是4。

异步IO都要占用线程池?

答案:并不是,网络IO不会占用线程池

const http = require('http');http.createServer((req, res) => {  http.get('http://192.168.1.100');  res.end('hello');}).listen(8000, () => {  console.log('server is listening: ' + 8000);});

上面这段代码,使用ab压测

ab -n10000 -c20 'http://192.168.76.101:8000'

无论多少次访问都不会创建线程,线程数永远为6。

文件IO一定会占用线程池?

答案:并不是,*Sync会阻塞主线程所以不会占用线程池,另外fs.FSWatcher也不会占用线程池。

虽然官方文档里面提到了fs.FSWatcher,但是其实并不能直接调用,关于FSWatcher访问 StackOverflow上有一个相关的提问

线程池只能用于异步IO?

答案:并不是,除了一些IO密集操作外,Node.js对一些CPU密集的操作也会放到线程池里面执行(Crypto、Zlib模块)

DNS查询也有可能占用线程池?

答案:是的,因为dns.lookup方法会涉及到读取本地文件(例如nsswitch.conf,resolv.conf 以及 /etc/hosts)。而dns.resolve方法就不会占用线程池,这也是lookup和resolve的区别所在。

所以下面的代码,其实是会占用线程池的,因为http.get在dns解析的时候默认使用的是lookup方法。

const http = require('http');http.createServer((req, res) => {  http.get('http://bj.meituan.com');  res.end('hello');}).listen(8000, () => {  console.log('server is listening: ' + 8000);});

线程池只供Node.js核心模块内部使用?

答案:不是的,官方文档里面有如下描述

You can use the built-in Node Worker Pool by developing a . On older versions of Node, build your C++ addon using , and on newer versions use . offers a JavaScript-only way to access Node's Worker Pool.

线程池内线程数可以为0吗,可以无限大吗?

答案:不可以为0,也不是无限大的。通过UV_THREADPOOL_SIZE可以修改线程池的线程数(默认为4),线程数最大值为128,最小值为1。

主线程任何时候都不会阻塞吗?

答案:不是的,主线程在特定的情况下是会阻塞的。Node.js的事件循环中有一个阶段是poll,poll阶段在特定情况下是会阻塞的。这就是下图服务启动起来没有任何用户请求的时候Event Loop执行一次的时间比有少量请求的时候还要长的原因。

图片来源:

参考资料

转载地址:http://qgmyx.baihongyu.com/

你可能感兴趣的文章
12.04 安装svn
查看>>
2017 3月15日 上午
查看>>
基于神念TGAM的脑波小车(1)
查看>>
ceph集群搭建Jewel版本
查看>>
HttpClient 解释
查看>>
111111
查看>>
在Button上面显示图片,去掉Button的默认样式
查看>>
区域生长算法
查看>>
(转)json+flexgrid+jbox组合运用页面刷新<jsp>
查看>>
hive学习2(Navicat连接hive)
查看>>
getResourceAsStream的3种路径配置
查看>>
switch语句小练习
查看>>
组合逻辑电路
查看>>
POP-一个点击带有放大还原的动画效果
查看>>
9款极具创意的HTML5/CSS3进度条动画
查看>>
uboot在s3c2440上的移植(1)
查看>>
安装webpack
查看>>
Python 抓取网页乱码问题 以及EXCEL乱码
查看>>
https连接加载http资源
查看>>
个人阅读作业2
查看>>