Nodejs child_process fork 子进程并send socket后,主进程对socket还有什么控制吗?
Nodejs child_process fork 子进程并send socket后,主进程对socket还有什么控制吗?
我在主进程中,fork了四个子进程,主进程监听端口号,建立socket后,send到子进程。
这之后,这个socket是完全属于子进程,还是主进程对其还有控制? 因为子进程在对客户端通信时,应该没有主进程的什么事,但这时为什么主进程的cpu会很高?
在Node.js中使用child_process.fork()
创建子进程,并通过process.send()
发送数据给子进程时,实际上你是在创建一个IPC(Inter-Process Communication)通道。当你将一个socket对象从主进程发送到子进程时,实际上你只是发送了一个引用或句柄,而不是整个socket对象本身。这意味着子进程可以接管这个socket的读写操作,但这并不意味着主进程完全失去了对这个socket的控制。
然而,一旦socket被发送到子进程,主进程将不再直接控制该socket。任何对这个socket的进一步操作都需要通过IPC通道与子进程通信来完成。例如,如果你想在主进程中关闭这个socket,你需要先向子进程发送一个消息,让子进程执行关闭操作。
示例代码
主进程 (master.js)
const { fork } = require('child_process');
const net = require('net');
const server = net.createServer((client) => {
console.log('New client connected');
// 创建子进程
const worker = fork('./worker.js');
// 发送socket句柄给子进程
worker.send({ type: 'socket', socket: client });
});
server.listen(3000, () => {
console.log('Server listening on port 3000');
});
子进程 (worker.js)
process.on('message', (msg) => {
if (msg.type === 'socket') {
const client = msg.socket;
// 处理客户端数据
client.on('data', (data) => {
console.log(`Received data: ${data}`);
});
// 关闭socket
client.end();
}
});
在这个例子中,主进程创建了一个TCP服务器,并在接收到新的客户端连接时,将socket对象传递给子进程处理。主进程不再直接控制这个socket,而是通过IPC通道与子进程通信来间接管理。
关于CPU使用率高的问题,如果主进程的CPU使用率很高,可能是因为它正在不断地检查或处理一些事件,比如频繁地检查是否有新连接,或者处理其他类型的事件。你可以优化主进程的逻辑,减少不必要的轮询或事件处理,从而降低CPU使用率。
当您使用 child_process.fork
将一个 socket 发送到子进程后,这个 socket 主要会由子进程接管处理。然而,主进程仍然可以对 socket 进行一些基本的操作,比如关闭或销毁该 socket。不过,一旦 socket 被发送给子进程,主进程对该 socket 的直接操作将受到限制。
如果主进程的 CPU 使用率很高,可能是因为主进程还在做某些未提及的工作,例如继续监听新的连接请求、处理与子进程之间的通信等。
示例代码
主进程代码
const { fork } = require('child_process');
const net = require('net');
const server = net.createServer();
server.listen(3000, () => {
console.log("Server is listening on port 3000");
});
server.on('connection', (socket) => {
console.log('New client connected.');
// Fork a child process and send the socket to it
const child = fork('./child.js');
child.send('socket', socket);
});
子进程代码(child.js)
process.on('message', (msg, socket) => {
if (msg === 'socket') {
console.log('Received socket in child process.');
// Handle socket in the child process
socket.on('data', (data) => {
console.log(`Data received: ${data}`);
socket.write(data); // Echo back the data
});
socket.on('end', () => {
console.log('Client disconnected.');
});
}
});
在这个例子中,主进程负责创建一个 TCP 服务器,并在有新客户端连接时启动一个子进程。然后,它将客户端的 socket 通过 process.send
方法传递给子进程。子进程接收到 socket 后,可以在子进程中进行进一步的处理,如接收数据和回显。此时,主进程的 CPU 使用率应该不会因为这个特定的 socket 处理而显著提高,除非主进程还执行了其他任务。