Pre:
单线程可以理解为一个程序端口,只有一个main函数顺序执行,不需要同时执行其他main函数,js语言不支持多线程
异步io是因为有直接存储器dma,dma操作的时候并不完全依赖cpu,很多io操作都交给了dma来完成
但是这就会有一个问题:
有些时候cpu没有事情做闲着,等待返回数据,有些时候因为有计算工作,一直很忙卡到那了,没空处理返回数据,cpu利用率不高。
这时候就需要多线程,同时执行多个main函数,依次排队,等待cpu资源,使cpu的利用率提高。
worker_threads利用了node的核心v8引擎本身的特性,js不允许多线程,但是js的容器,v8或者浏览器,是允许多线程的。
这样就可以在一个端口,也就是一个进程中,生成多个node实例,多个js环境,以及多个单独的异步io事件操作,然后之间数据传递通过dma进行,同一个变量并不是在多个环境中同时处理,不断变化,而是通过io操作流转,每次都把workerData复制出来单向传递,保证了数据的前后一致性,当然你如果不想来回传递数据,也可以采用cluster的老方法,线程共享内存
但是,并不必要为了多线程而多线程,只有针对需要大量计算工作的时候,我们才需要单开线程,很多时候使用线程池也就可以了
一、how to use?
在git上传了小项目,目录粘到这里,其他的可以自己具体去看代码,注释的很清楚
01-worker_pool.js //线程池的实现
02-cpu_worker.js //接01,线程池中用到的耗时事件
03-pc_woker_threads.js //父线程和子线程的数据交换
04-cc_worker_threads.js //子线程之间的数据交换
05-cc_worker.js //接04,子线程数据交换中的线程2
其中比较重要也是比较常用的是:
01-worker_pool.js 也就是线程池的实现和使用部分,02-cpu_worker.js是提供耗时计算
里边大体实现的内容:
------------------------线程池的实现-----------------------------
1.线程池的初始化,构造函数接收两个参数,要执行耗时操作的文件路径,要开启线程的个数
2.查询是否有闲置线程
3.在闲置线程中运行耗时操作,传递消息
4.耗时操作完全结束后返回信息,销毁线程
------------------------线程池的使用----------------------------
5.线程池的对象的初始化和结果的获取
PS:因为worker_threads还在测试阶段,所以在node 文件名.js的时候需要加flag,提示是实验线程;
eg:
node --experimental-worker 01-worker_pool.js
具体还是看代码:
github:https://github.com/canwhite/QCNodeWorkerThreads
POST:
https://www.jb51.net/article/158538.htm
https://blog.csdn.net/zero_person_xianzi/article/details/99412641
https://juejin.im/post/5c63b5676fb9a049ac79a798