NodeJS派生的Python进程 - Python中process.send()的替代方案?
我正在用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'的回调中收到消息。
干杯!