Nodejs child_process fork 子进程并send socket后,主进程对socket还有什么控制吗?

Nodejs child_process fork 子进程并send socket后,主进程对socket还有什么控制吗?

我在主进程中,fork了四个子进程,主进程监听端口号,建立socket后,send到子进程。

这之后,这个socket是完全属于子进程,还是主进程对其还有控制? 因为子进程在对客户端通信时,应该没有主进程的什么事,但这时为什么主进程的cpu会很高?

2 回复

在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 处理而显著提高,除非主进程还执行了其他任务。

回到顶部