欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

NodeJs 多线程(worker_threads)

程序员文章站 2022-06-21 22:06:35
Javascript的运行,我们知道是单线程的,目的是为了解决内存冲突等的问题,同时单线程的设计也方便问题的查找和解决,在浏览器端,单线程基本都可以满足,但是在NodeJS服务端的话,如果有大规模的计算或者耗时业务流程就会堵塞后面的请求,比如有一个客户端请求,需要从数据库里面取出数据,然后进行各种计算,一般计算过程都是用JS写的,如果这个计算过程很耗时(假如需要10s),就会导致后面的请求得不到响应,之前我们的做法就是N-API写一个C++的addon去开辟新线程去计算或者直接用模块child-proces...

Javascript的运行,我们知道是单线程的,目的是为了解决内存冲突等的问题,同时单线程的设计也方便问题的查找和解决,在浏览器端,单线程基本都可以满足,但是在NodeJS服务端的话,如果有大规模的计算或者耗时业务流程就会堵塞后面的请求,比如有一个客户端请求,需要从数据库里面取出数据,然后进行各种计算,一般计算过程都是用JS写的,如果这个计算过程很耗时(假如需要10s),就会导致后面的请求得不到响应,之前我们的做法就是N-API写一个C++的addon去开辟新线程去计算或者直接用模块child-process开辟一个新的js进程去计算,等返回之后再用主进程的JS去处理。

worker_threads是NodeJS team开发的真线程模块,可以做到真线程的原因当然是v8-isolate,v8-isolate是Chromium runtime 的一个独立的实例,我们的worker是完全独立于其他worker运行的,有独立的context, 也就是有独立的v8和event loop,与模块child_process和cluster的区别是能share memory,某种程度上可以克服performance和memory的问题。

子线程的执行过程:

1. 创建独立的v8 isolate,并且assgin给worker, 这使worker有独立的context。

2. libuv初始化,这让worker有独立的event loop。

3. worker开始真正的执行,event loop开始运行。

4. worker调用c++,读取主线程发过来的workerData。

5. worker执行js 文件或者code。作为独立线程运行。

parent线程创建子线程时的初始化过程:

1. 通过worker_threads创建一个worker。

2. 调用c++创建一个C++worker 对象,实际上是个空对象。

3. 给C++ worker对象创建线程ID。

4. C++ worker对象创建initialisation message channel,

5. 一个public message channel 的JS对象被创建,用来父线程和子线程通过postMessage函数互相通信。

6. 父线程调用C++发送workerData对象到c++ message channel,该对象用来传输给子线程初始化的时候调用。

下面的几个参考网页:

为什么需要多线程

NodeJS网站

 

本文地址:https://blog.csdn.net/SpringDou/article/details/107337686

相关标签: NodeJS