专栏首页M不作声Node开启多线程多进程

Node开启多线程多进程

Node的多进程和多线程问题

我们知道Node.js是以单线程的模式运行的,但它使用的是事件驱动来处理并发,这样有助于我们在多核cpu的系统上创建多个进程,从而提高性能。

面试官:问你Node能开启多线程吗? 你:No problem!

开启多进程

node中开启多进程有两个模块:child_process模块的cluster模块。

child_process模块可以实现子进程,从而实现广义的多进程模式。

child_process模块中提供了四个创建子进程的方法,区别如下:

  • spawn:子进程中执行的是非node程序,提供一组参数后,执行的结果以流的形式返回
  • execFile:子进程中执行的是非node程序,提供一组参数后,执行的结果以回调的形式返回
  • exec:子进程中执行的是非node程序,提供一组shell命令,执行的结果以回调的形式返回
  • fork:子进程中执行的是node程序,提供一组参数后,执行的结果以流的形式返回

node中的主进程称为Master线程,子进程称为Worker进程。在创建子进程之后,父子进程就可以开始进行通信。

单个Node.js实例运行在单个线程中。为了充分利用多核系统,有时候需要启用一组Node.js进程去处理负载任务。

cluster模块可以创建共享服务器端口的子进程。

工作进程由child_process.fork()方法创建,因此它们可以使用IPC和父进程通信,从而使各进程交替处理连接服务。

进程之间的通信

在NodeJS中,父子进程之间的通信可以通过on('message')send()方法实现通信。on('nessage')用来监听message事件,使用send()向其他进程发送消息。

面试官:多个进程可以监听同一个端口吗

主进程和worker可以监听同一个端口,但是master进程是不会处理具体业务的,因此需要使用worker去处理事务。当网络请求到来的时候,会进行抢占式调度。最后只会有一个master抢到任务并且处理。

除了父子进程之间的通信,还有别的通信方式。大概有如下几种:

  • stdin/stdout传递json。是最直接的方式,适用于关联进程之间的通信,无法跨机器。
  • node原生IPC。同样的约束。
  • 通过sockets。这是最通用的方式,有良好的跨环境能力,但存在网络性能消耗的问题。
  • 借助message queue。是为通信问题而扩展出的一层强大的消息中间件。

开启多线程

worker_threads模块允许使用并行地执行JavaScript的线程。

worker_threads相对于I/O密集型操作是没有太大的帮助的,因为异步的I/O操作比worker线程更有效率,但对于CPU密集型操作的性能会提升很大。

线程间的通信方式有:

  • 共享内存。线程之间可以共享内存,使用ArrayBufferSharedArrayBuffer
  • parentPort。主要用于父子线程通信,通过经典的on('message'),postMessage形式。
  • MessageChannel。创建自定义的消息传递通道。

Web 工作线程cluster 模块一样,可以通过线程间的消息传递来实现双向通信。 在内部,一个 Worker 具有一对内置的 MessagePort,在创建该 Worker 时它们已经相互关联。 虽然父端的 MessagePort 对象没有直接公开,但其功能是通过父线程的 Worker 对象上的 worker.postMessage()worker.on('message') 事件公开的。 要创建自定义的消息传递通道(建议使用默认的全局通道,因为这样可以促进关联点的分离),用户可以在任一线程上创建一个 MessageChannel 对象,并将该 MessageChannel 上的 MessagePort 中的一个通过预先存在的通道传给另一个线程,例如全局的通道。

总结

  • 开启多进程使用child_process模块或cluster模块,开启多线程使用worker_threads模块
  • 进程创建有四个方法spawnexecexecFilefork
  • 进程通信方式有stdin/stdout传递jsonnode原生IPCsocketsmessage queue
  • 线程通信方式共享内存、parentPortMessageChannel

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 用JS手动实现一个栈和队列

    栈是一个「线性」的数据结构。栈最重要的特征是「只允许从一端操作数据」。栈就像一叠书,或者盘子,每次只能从最上边拿,往最上边放。

    不作声
  • 二叉树的实现、遍历及面试题

    如图就是一个树结构,最上边的叫「根节点」,最下边的叫「叶子节点」。根节点有多个子节点,叶子节点没有子节点。二叉树就是,每个节点最多有两个子节点的树。

    不作声
  • 628笔试题

    第一次输出[9,2,3] [9,2,3],第二次输出[4,5,6] [9,2,3]

    不作声
  • vue原理及其手撸(二)

    在due.js中的Due构造函数中·new Complie(this.$option.el,this). 在浏览器环境秀泡一下:

    一粒小麦
  • Akka 指南 之「调度器」

    调度器(Dispatchers)是 Akka 核心的一部分,这意味着它们也是akka-actor依赖的一部分:

    CG国斌
  • php基础教程 第八步循环补充

    上一节内容中,讲解了php中的循环,并且了解了for循环。for循环是php循环中的一种,在本节中继续讲解php循环:While循环、do…while循环、fo...

    公众号 碧油鸡
  • 逆序排序遇到`Not-static method cannot be referenced from a static context`

    IDEA会提示错误:Not-static method cannot be referenced from a static context

    十毛
  • WeChat 模块、模板与缓存

    本次的系列博文的知识点讲解和代码,主要是来自于 七月老师 的书籍《微信小程序开发:入门与实践》,由个人总结并编写,关于更多微信小程序开发中的各项技能,以及常见问...

    Nian糕
  • python爬虫学习:电商数据分析

    通常我们在使用爬虫的时候会爬取很多数据,而这些数据里边什么是有用的数据,什么是没用的数据这个是值得我们关注的,在这一篇文章里,我们将通过一个简单的爬虫,来去简单...

    云时之间
  • python爬虫学习:电商数据分析

    通常我们在使用爬虫的时候会爬取很多数据,而这些数据里边什么是有用的数据,什么是没用的数据这个是值得我们关注的,在这一篇文章里,我们将通过一个简单的爬虫,来去简单...

    用户1332428

扫码关注云+社区

领取腾讯云代金券