NodeJS派生的Python进程 - Python中process.send()的替代方案?

8 投票
2 回答
3001 浏览
提问于 2025-04-18 07:18

我正在用NodeJS来分叉一个Python脚本,当分叉时,NodeJS默认会在这个新进程和父进程之间创建一个通信通道。

在NodeJS中,要从子进程向父进程发送消息,我可以用 process.send({msg : 'toto'}) 这个命令。

那么在Python中,我该怎么做呢?

http://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options

2 个回答

0

在按照@Unitech的回答操作后,我遇到了一些问题,发现事情比我想的要复杂一些。我不确定这是否跟我的Node版本有关,或者是其他原因。(我用的是v16.13.1和python 3.10.8)不过,看起来消息交换的方式发生了变化。现在消息的开头有8个字节的内容,接着是8个字节的消息长度,采用的是小端格式。

无论如何,我写了以下的python代码,成功地发送和接收了消息。

import os
import json

# get the FD from ENV
NODEIPCFD = int(os.environ["NODE_CHANNEL_FD"])

def sendMessage(text):
  'sends a Node IPC message to parent proccess'
  # encode message as json string + newline in bytes
  bytesMessage = (json.dumps(text) + "\n").encode()
  # I'm not actually sure what this number is for,
  # but not including it causes problems.
  # probably encodes something to do with the 'advanced' serialization
  os.write(NODEIPCFD, int.to_bytes(1, 8, "little"))
  # send the length as an 8-byte number in little Endian format
  os.write(NODEIPCFD, len(bytesMessage).to_bytes(8, "little"))
  # send message
  os.write(NODEIPCFD, bytesMessage)


def readMessage():
  'read in next message from parent Node process via built-in node IPC'
  # read and discard 8 bytes. Again, don't know why...
  os.read(NODEIPCFD, 8)
  # read and parse 8 bytes as length in little Endian format
  length = int.from_bytes(os.read(NODEIPCFD, 8), "little")
  # read 'length' bytes and pass to json parser
  return json.loads(os.read(NODEIPCFD, length))

我在Node端用这个启动了python代码:

const child_process = require('node:child_process');

var cp = child_process.spawn('python', ['child_process.py'], {
  stdio:[null, null, null, 'ipc']
});

我只是希望Node的文档能包含关于消息交换过程的详细说明。

15

好的,我找到了,实际上这很简单。关键在于写入正确的文件描述符。

在NodeJS这边,启动你的脚本可以这样写:

var child = child_process.spawn('python', ['hello.py'], {
  stdio:[null, null, null, 'ipc']
});

child.on('message', function(message) {
  console.log('Received message...');
  console.log(message);
});

因为'ipc'通道是第四个参数,所以你需要在文件描述符3上进行写入。

在Python这边:

import os

os.write(3, '{"dt" : "This is a test"}\n', "utf8")

完成了。你会在child.on('message'的回调中收到消息。

干杯!

撰写回答