如何正确处理spawn生成的子进程的stdio以避免跨进程通讯阻塞?
问题根因
- Python进程的stdout管道缓冲区已满被阻塞:你的Python代码使用logging同时向文件和stdout输出日志,而Node.js侧没有消费Python子进程的stdout输出,管道缓冲区(默认大小通常为64KB)写满后,Python会直接阻塞在
tempLogger.info(inp)这行代码,自然无法继续读取stdin的新输入。你遇到的79次停止就是刚好累计日志输出达到了缓冲区上限。 - 可选的次要影响:Python在非TTY环境(被Node.js子进程调用时)默认对stdin/stdout启用块缓冲,即使缓冲区没满也可能出现输出延迟。
修复方案
1. Node.js侧新增子进程输出消费逻辑
必须监听Python子进程的stdout和stderr输出,哪怕不需要打印内容也要把数据读走,避免缓冲区溢出。修改后的temp.js新增以下代码:
// 原有代码保持不变,新增以下内容 pythonProcess.stdout.on("data", (data) => { // 不需要日志可直接空处理,只要完成读取动作即可清空缓冲区 // console.log('Python输出:', data.toString()) }); pythonProcess.stderr.on("data", (data) => { // 错误输出建议保留打印,方便排查问题 console.error('Python运行错误:', data.toString()) });
2. 可选:禁用Python I/O缓冲
启动Python进程时添加-u参数,强制关闭stdin/stdout/stderr的块缓冲,避免不必要的延迟:
// 将原来的spawn行修改为以下内容 let pythonProcess = childProcess.spawn("python", ["-u", "temp2.py"], {cwd: "./private/PythonScripts/Temp/"});
3. 可选:处理stdin背压(高并发场景建议加)
如果后续写入频率更高、写入内容更大,可监听pythonProcess.stdin的drain事件,当write返回false时暂停写入,等待drain触发后再恢复,避免内存溢出。
完成以上修改后即可解决通讯中断问题。
内容的提问来源于stack exchange,提问作者Hokkyokusei
相关产品推荐
相关产品推荐

