node进程间如何通信?下面本篇文章带大家了解node进程的通信方式,以及在node中如何实现这些方式的通信,希望对大家有所帮助!
通信其实涵盖开发的各个层面,常见的有客户端和服务端通过各种通信协议进行通信,RPC通信,开发过程中各个模块之间的相互通信,electron主进程和渲染进程之间的通信等等;
本文主要是尝试总结下nodejs(单线程,多线程,多进程)通信的方式,使用场景,实现等。
通信的实现方式
一般进程通信的实现方式如下:
1、Shared Memory(内存共享);
2、Socket(套接字);
3、管道(非命名管道Pipe, 命名管道FIFO);
4、Signal(信号);
5、Message queue(消息队列);
下面我们看下在node中如何实现这些方式的通信
一、Shared Memory(内存共享)
单机下(客户端内单线程,单进程里多线程,单台服务器内多进程),通过内存共享实现通信的方式最为常见。
Shared Memory(内存共享)-单线程
从操作系统层面来看,进程内所有线程内存都是共享的,但前提是需要知道内存的访问地址。
但从语言层面(node或者说是v8的实现层面),我们没有直接接触内存的管理,而是间接从v8提供的语法/api进行内存操作。v8提供三种方式给我们共享内存(也许叫共享变量更恰当):全局变量, 局部变量, 共享传参(call by sharing);
v8在执行代码之前会先将代码通过Estree规范转化为抽象语法树后再进行解释编译执行,在抽象语法树中(关于抽象语法树可查看我另外一篇文章)是有scope的,而内存读取是通过标志符(变量命名)逐级往上回溯查找。所以如果你需要在两个方法之间共享某个内存,可以在他们共同的作用域下进行创建。
Shared Memory(内存共享)-多线程
在客户端环境或node环境,我们都可以实现多线程,两者方式也类似(node通过worker_threads实现,浏览器通过Worker实现)。这里的内存共享主要是借助内存操作的api(SharedArrayBuffer)实现的。先看下浏览器实现的例子:
// 主线程 const buffer = new SharedArrayBuffer(1024) const typedArr = new Int16Array(buffer) const newWorker = new Worker('./worker.js') typedArr[0] = 20 newWorker.postMessage(buffer) newWorker.onmessage= (data) => { console.group('[the main thread]'); console.log('Data received from the main thread: %i', typedArr[0]); console.groupEnd(); } // 子线程 addEventListener('message', ({ data }) => { const arr = new Int16Array(data) console.group('[the worker thread]') console.log('Data received from the main thread: %i', arr[0]) console.groupEnd() arr[0] = 18 postMessage('Updated') }) // 结果 [the worker thread] Data received from the main thread: 20 [the main thread] Data received from the main thread: 18
Shared Memory(内存共享)-多进程
因为进程启动后内存是无法相互读取的(系统层面的限制),进程之间的内存共享实际是通过新开辟一段shared memory实现的。但node暂时没有支持shared memory,只能通过低级语言来实现,例如: c++实现的 shared-memory-disruptor addon插件(另外文章介绍)。
二、Socket(套接字)
Socket 分两种实现:
1、TCP Socket;
2、UNIX Domain Socket;
两者的主要区别如下:
TCP Socket适用于单机,C/S架构等.但UNIX Domain Socket只适用于单机。 UNIX Domain Socket不需要经过一系列的网络中转(协议,分包,校验等等),性能更高,稳定性更好。
TCP Socket
概念: TCP Socket是应用层与TCP/IP协议族通信的中间抽象层,是一种操作系统提供的进程间通信机制;
TCP Socket通信应该是我们日常开发(C/S架构)中最常见的通信方式之一,在我们日常开发中最常见的就是各种应用层协议(http,websocket,rpc,ftp等)的使用,node中http模块也是基于net模块实现的。
注:其实UDP也属于TCP分层(并不是严格的指TCP通信,而是网络通信层中的TCP/IP层),node有提供'dgram'模块来实现,但在实际应用中没有接触过,所以不进行了解。
net
在node中,TCP Socket是由net模块实现的,net模块主要提供了以下功能:
1、上层的IPC支持(实际上是管道通信的实现,后面管道通信再详细说明);
2、net.Server类;
// 服务端通过net.createServer创建服务,会返回net.Server对象,可以通过返回值进行各种事件监听,端口监听 const net = require('net') net.createServer((server => { server.end(`hello world!\n`) })).listen(3302, () => { console.log(`running ...`) })
3、net.Socket类;
const net = require('net') const socket = net.createConnection({port: 3302}) socket.on('data', data => { console.log(data.toString()) })
UNIX Domain Socket
UNIX Domain Socket是通过创建一个文件描述符,不同进程之间的通信通过读写这个文件描述符进行通信(可以分为创建进程和其他进程,其他进程之间的相互通信可以通过创建进程作为中转)。e.g.
// 创建进程 const net = require('net') const unixSocketServer = net.createServer(server => { server.on('data', data => { console.log(`receive data: ${data}`) }) }) unixSocketServer.listen('/tmp/test', () => { console.log('listening...') }) // 其他进程 const net = require('net') const socket = net.createConnection({path: '/tmp/test'}) socket.on('data', data => { console.log(data.toString()) }) socket.write('my name is vb') // 输出结果 listening... receive data: my name is vb
三、管道
管道通信分两种,非命名管道和命名管道。
非命名管道的实现方式和UNIX Domain Socket一样,都是通过创建文件描述符进行通信。
命名管道是通过固定的文件描述符进行通信:
"\\\\.\\pipe\\" + PIPE_NAME;
源码可参考stackoverflow(https://stackoverflow.com/questions/11750041/how-to-create-a-named-pipe-in-node-js)
目前理解的管道通信和UNIX Domain Socket实现基本一致,只是管道通信规范了读写权限,半双工通信,UNIX Domain Socket更加自由一些。
四、Signal(信号)
Signal是操作系统在终止进程前给进程发送的信号。在node中可以通过process.kill(pid, signal)/child_process.kill(pid, signal)接口实现,e.g.
// 要被终止的http守护进程 const Koa = require('koa') const app = new Koa() app.listen(3004, () => { console.log(`process pid is : ${process.pid}`) // process pid is : 75208 }) // 操作进程 process.kill(75208, 'SIGHUP') // 'SIGHUP'是一般结束进程的信号,还有更多其他的信号参考 [标识](https://blog.csdn.net/houjixin/article/details/71430489)
但这里的前提是你需要获取到被终止的进程pid,更多pid的内容可阅读我之前关于进程的文章。
五、Message queue(消息队列)
一开始我以为是redis,各种MQ之类的基于TCP的消息队列。但其实是操作系统内的消息队列,node暂时没有提供相关的上层接口,需要更底层实现,e.g. svmq
更多node相关知识,请访问:nodejs 教程!!
以上是详解node中进程通信的几种实现方式的详细内容。更多信息请关注PHP中文网其他相关文章!

从C/C 转向JavaScript需要适应动态类型、垃圾回收和异步编程等特点。1)C/C 是静态类型语言,需手动管理内存,而JavaScript是动态类型,垃圾回收自动处理。2)C/C 需编译成机器码,JavaScript则为解释型语言。3)JavaScript引入闭包、原型链和Promise等概念,增强了灵活性和异步编程能力。

不同JavaScript引擎在解析和执行JavaScript代码时,效果会有所不同,因为每个引擎的实现原理和优化策略各有差异。1.词法分析:将源码转换为词法单元。2.语法分析:生成抽象语法树。3.优化和编译:通过JIT编译器生成机器码。4.执行:运行机器码。V8引擎通过即时编译和隐藏类优化,SpiderMonkey使用类型推断系统,导致在相同代码上的性能表现不同。

JavaScript在现实世界中的应用包括服务器端编程、移动应用开发和物联网控制:1.通过Node.js实现服务器端编程,适用于高并发请求处理。2.通过ReactNative进行移动应用开发,支持跨平台部署。3.通过Johnny-Five库用于物联网设备控制,适用于硬件交互。

我使用您的日常技术工具构建了功能性的多租户SaaS应用程序(一个Edtech应用程序),您可以做同样的事情。 首先,什么是多租户SaaS应用程序? 多租户SaaS应用程序可让您从唱歌中为多个客户提供服务

本文展示了与许可证确保的后端的前端集成,并使用Next.js构建功能性Edtech SaaS应用程序。 前端获取用户权限以控制UI的可见性并确保API要求遵守角色库

JavaScript是现代Web开发的核心语言,因其多样性和灵活性而广泛应用。1)前端开发:通过DOM操作和现代框架(如React、Vue.js、Angular)构建动态网页和单页面应用。2)服务器端开发:Node.js利用非阻塞I/O模型处理高并发和实时应用。3)移动和桌面应用开发:通过ReactNative和Electron实现跨平台开发,提高开发效率。

JavaScript的最新趋势包括TypeScript的崛起、现代框架和库的流行以及WebAssembly的应用。未来前景涵盖更强大的类型系统、服务器端JavaScript的发展、人工智能和机器学习的扩展以及物联网和边缘计算的潜力。

JavaScript是现代Web开发的基石,它的主要功能包括事件驱动编程、动态内容生成和异步编程。1)事件驱动编程允许网页根据用户操作动态变化。2)动态内容生成使得页面内容可以根据条件调整。3)异步编程确保用户界面不被阻塞。JavaScript广泛应用于网页交互、单页面应用和服务器端开发,极大地提升了用户体验和跨平台开发的灵活性。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

安全考试浏览器
Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

螳螂BT
Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

SecLists
SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

ZendStudio 13.5.1 Mac
功能强大的PHP集成开发环境