通信方式
Node.js 进程间可以通过以下几种方式进行通信:
- 子进程与父进程间的通信:可以使用
child_process模块中的send()方法和on("message")事件来实现。父进程可以通过child_process.fork()方法启动一个子进程,并且使用send()方法来向子进程发送消息,子进程可以通过process.on("message")事件来监听父进程发送的消息。 - 父进程与子进程间的通信:与上面的方式相反,可以使用
process.send()方法和on("message")事件来实现。这种方式通常用于父进程与子进程之间的协作,比如启动子进程处理一些耗时的任务,然后将处理结果发送回父进程。 - 进程间共享内存:可以使用
Buffer对象、SharedArrayBuffer对象、TypedArray对象等方式在不同的进程间共享内存。这种方式通常用于需要高效地共享数据的场景,比如多个进程同时处理大量数据的情况。 - 进程间信号量通信:可以使用
process.kill()方法向另一个进程发送信号,比如SIGUSR1和SIGUSR2信号。这种方式通常用于进程间的控制和协作,比如向另一个进程发送停止信号、重启信号等。 总之,Node.js 进程间可以通过不同的方式进行通信,可以根据具体的需求选择适合的方式。在实际应用中,通常会结合多种方式来实现进程间的协作和通信。
示例1: 父子进程间通信
父进程代码:
javascriptCopy code
const { fork } = require("child_process");
// 启动子进程
const child = fork("./child.js");
// 监听子进程发送的消息
child.on("message", (msg) => {
console.log(`Received message from child process: ${msg}`);
});
// 向子进程发送消息
child.send("Hello from parent process!");
子进程代码:
javascriptCopy code
// 监听父进程发送的消息
process.on("message", (msg) => {
console.log(`Received message from parent process: ${msg}`);
// 向父进程发送消息
process.send("Hello from child process!");
});
在上面的例子中,父进程通过 fork() 方法启动了一个子进程,并且监听了子进程发送的消息。子进程则通过 process.on("message") 方法监听父进程发送的消息,并且在接收到消息后向父进程发送了一个回复消息。通过这种方式,父进程和子进程之间就可以进行通信了。
示例2: 进程间共享内存来通信
const { Worker, isMainThread, workerData } = require("worker_threads");
if (isMainThread) {
// 主线程创建共享内存
const buffer = new SharedArrayBuffer(4);
// 创建子线程,并传入共享内存
const worker = new Worker(__filename, { workerData: buffer });
// 监听子线程发送的消息
worker.on("message", (msg) => {
console.log(`Received message from worker thread: ${msg}`);
console.log(`SharedArrayBuffer value is: ${new Int32Array(buffer)[0]}`);
});
// 向子线程发送消息,并修改共享内存中的值
new Int32Array(buffer)[0] = 42;
worker.postMessage("Hello from main thread!");
} else {
// 子线程读取共享内存,并向主线程发送消息
const buffer = workerData;
console.log(`SharedArrayBuffer value is: ${new Int32Array(buffer)[0]}`);
process.on("message", (msg) => {
console.log(`Received message from main thread: ${msg}`);
new Int32Array(buffer)[0] = 100;
// 向主线程发送消息,并修改共享内存中的值
process.send("Hello from worker thread!");
});
}
在上面的例子中,主线程创建了一个 SharedArrayBuffer 对象,并将其传递给子线程。主线程修改了共享内存中的值,并向子线程发送了一个消息。子线程读取共享内存中的值,并向主线程发送了一个回复消息,并修改了共享内存中的值。通过这种方式,主线程和子线程之间就可以共享内存并进行通信了。
示例3:进程间信号量通信
const { spawn } = require("child_process");
// 启动子进程
const child = spawn("node", ["child.js"]);
// 监听子进程的 stdout 输出
child.stdout.on("data", (data) => {
console.log(`Received message from child process: ${data}`);
});
// 向子进程发送 SIGUSR1 信号
child.kill("SIGUSR1");
子进程代码(child.js):
// 监听 SIGUSR1 信号
process.on("SIGUSR1", () => {
console.log("Received signal from parent process!");
// 向父进程发送消息
process.stdout.write("Hello from child process!");
});
在上面的例子中,父进程通过 spawn() 方法启动了一个子进程,并且监听子进程的 stdout 输出。父进程向子进程发送了一个 SIGUSR1 信号,子进程收到信号后向父进程发送了一条消息,并输出到 stdout。通过这种方式,父进程和子进程之间就可以使用进程间信号量进行通信了。