你好,我是Alan,我们都知道进程是操作系统调度的单位,但是进程的开销也是比较高的,因此我们是需要谨慎使用的。
今天这篇文章我主要想向你介绍一下关于操作系统的进程是进行通信的,我们主要是用 nodejs 中的一些模块来进行演示。
Node.js 内部通过两个库创建子进程:child_process 和 cluster, 这篇主要是用 child_process 这个库来进行演示的。
我们首先可以通过 fork 函数来创建对应的子进程,fork函数的参数是对应的模块路径。
const childProcess = ChildProcess.fork("./child.js");
我们在子进程中使用 send 函数向父进程中发送一条消息:
setInterval(() => {process.send(new Date());}, 2000)
然后在父进程中监听一下对应的对应的消息
childProcess.on('message', (msg) => {console.log("parent received", msg);});
然后分别执行,这样我们就可以实现父子进程之间的通信了
那么两个相互独立的模块之间如何进行通信呢, 我们知道在操作系统中两个进程之间通信可以通过共享内存,信号,socket,命名管道等进行通信, 同样在 nodejs 中也是一样的。
共享内存这种进程通信模式我暂时还没有在 nodejs 中见到过, 所以也无法介绍了:)
使用信号进行通信一般都有一个接收信号和发送信号的过程。
首先我们通过kill -USR2 3000首先发送一个信号,然后使用 on 监测一下
process.on('SIGUSR2', () => {console.log("来了老弟、USR2");});
看完了上面的通信过程下面我们来看一下使用 socket 进行通信: 首先我们创建一个server
const net = require('net');let server = net.createServer((client) => {client.on('data', (msg) => {//发送接收到的信息console.log(String(msg));//向客户端发送一条消息client.write('server send message');});});server.listen(8087);
然后创建一个client,用于与客户端之间的通信
const net = require('net');const client = new net.Socket();client.connect('8087', '127.0.0.1');client.on('data', data => console.log(String(data)));client.write('client send message');
第三种要介绍的是命名管道,首先创建一个命名管道mkfifo /tmp/nfifo,与一般的文件不同, 命名管道通常不会返回对应的值,而是在监听到对应的写的时候才会出现。
const fs = require('fs');//读取文件fs.readFile('/tmp/tmpipe', (data, err)=>{console.log(err, String(data));});//写文件fs.writeFile('/tmp/tmpipe', 'info to send', (data, err)=>{console.log(data, err);});
在nodejs中我们是可以直接在父子进程之间进行通信的,但是兄弟之间是无法进行通信的。如果你想在兄弟之间进行通信的话可以使用对应的unix域, 我觉得unix域是一种特殊的socket,废话不多说我们直接上源码。
//创建server过程同上server.on('connection', (client)=>{client.on('data', (msg) => {console.log(String(msg))});});server.listen('/tmp/unix.sock');//////客户端//////const net = require('net');const client = new net.Socket();client.connect('/tmp/unix.sock');client.on('data', data => console.log(String(data)));client.write('client send message');

