浅谈Nodejs中的多线程操作


当前第2页 返回上一页

先看下简单的 demo:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

const {

  isMainThread,

  parentPort,

  workerData,

  threadId,

  MessageChannel,

  MessagePort,

  Worker

} = require('worker_threads');

 

function mainThread() {

  for (let i = 0; i < 5; i++) {

    const worker = new Worker(__filename, { workerData: i });

    worker.on('exit', code => { console.log(`main: worker stopped with exit code ${code}`); });

    worker.on('message', msg => {

      console.log(`main: receive ${msg}`);

      worker.postMessage(msg + 1);

    });

  }

}

 

function workerThread() {

  console.log(`worker: workerDate ${workerData}`);

  parentPort.on('message', msg => {

    console.log(`worker: receive ${msg}`);

  }),

  parentPort.postMessage(workerData);

}

 

if (isMainThread) {

  mainThread();

} else {

  workerThread();

}

上述代码在主线程中开启五个子线程,并且主线程向子线程发送简单的消息。

由于 worker_thread 目前仍然处于实验阶段,所以启动时需要增加 --experimental-worker flag,运行后观察活动监视器:

5.gif

不多不少,正好多了五个子线程。

worker_thread 模块

worker_thread 核心代码

worker_thread 模块中有 4 个对象和 2 个类。

  • isMainThread: 是否是主线程,源码中是通过 threadId === 0 进行判断的。
  • MessagePort: 用于线程之间的通信,继承自 EventEmitter。
  • MessageChannel: 用于创建异步、双向通信的通道实例。
  • threadId: 线程 ID。
  • Worker: 用于在主线程中创建子线程。第一个参数为 filename,表示子线程执行的入口。
  • parentPort: 在 worker 线程里是表示父进程的 MessagePort 类型的对象,在主线程里为 null
  • workerData: 用于在主进程中向子进程传递数据(data 副本)

来看一个进程通信的例子:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

const assert = require('assert');

const {

  Worker,

  MessageChannel,

  MessagePort,

  isMainThread,

  parentPort

} = require('worker_threads');

if (isMainThread) {

  const worker = new Worker(__filename);

  const subChannel = new MessageChannel();

  worker.postMessage({ hereIsYourPort: subChannel.port1 }, [subChannel.port1]);

  subChannel.port2.on('message', (value) => {

    console.log('received:', value);

  });

} else {

  parentPort.once('message', (value) => {

    assert(value.hereIsYourPort instanceof MessagePort);

    value.hereIsYourPort.postMessage('the worker is sending this');

    value.hereIsYourPort.close();

  });

}

更多详细用法可以查看官方文档。

多进程 vs 多线程

根据大学课本上的说法:“进程是资源分配的最小单位,线程是CPU调度的最小单位”,这句话应付考试就够了,但是在实际工作中,我们还是要根据需求合理选择。

下面对比一下多线程与多进程:

属性多进程多线程比较
数据数据共享复杂,需要用IPC;数据是分开的,同步简单因为共享进程数据,数据共享简单,同步复杂各有千秋
CPU、内存占用内存多,切换复杂,CPU利用率低占用内存少,切换简单,CPU利用率高多线程更好
销毁、切换创建销毁、切换复杂,速度慢创建销毁、切换简单,速度很快多线程更好
coding编码简单、调试方便编码、调试复杂多进程更好
可靠性进程独立运行,不会相互影响线程同呼吸共命运多进程更好
分布式可用于多机多核分布式,易于扩展只能用于多核分布式多进程更好

上述比较仅表示一般情况,并不绝对。

work_thread 让 Node 有了真正的多线程能力,算是不小的进步。

更多编程相关知识,请访问:编程视频!!

以上就是浅谈Nodejs中的多线程操作的详细内容,更多文章请关注木庄网络博客

返回前面的内容

相关阅读 >>

nodejs的npm常用命令集合

浅谈nodejs中的?双工流

如何使用nodejs实现路由功能

详解nodejs中的阻塞和非阻塞

nodejs|使用mongoosejs将mongodb与node连接

nodejs的爬虫框架superagent

nodejs如何导入模块?require的执行过程介绍

nodejs 如何处理密集型计算

了解nodejs中的可读流

nodejs版的orm库--sequelize

更多相关阅读请进入《nodejs》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...