开始后分离一个生成子进程

问题描述 投票:5回答:1

我以这种方式启动生成子进程:

let process = spawn(apiPath, {
  detached: true
})

process.unref()

process.stdout.on('data', data => { /* do something */ })

启动该过程时,我需要保持其附件状态,因为我想读取其输出。但是在关闭我的Node进程(父进程)之前,我想分离所有未完成的子进程以使其在后台运行,但是正如the documentation所说的:

[当使用分离选项启动长时间运行的进程时,除非父进程没有提供未连接到父进程的stdio配置,否则该进程将在父进程退出后不会在后台继续运行。

但是使用选项stdio: 'ignore',我无法读取stdout,这是一个问题。

我试图在关闭父进程之前手动关闭管道,但未成功:

// Trigger just before the main process end
process.stdin.end()
process.stderr.unpipe()
process.stdout.unpipe()
node.js multithreading spawn
1个回答
0
投票

经过多次测试,我发现至少有一种方法可以解决此问题:在离开主进程之前销毁所有管道。

棘手的一点是,子进程必须正确处理销毁管道,如果没有,则可能会出错并仍然关闭。在此示例中,节点子进程对此似乎没有问题,但与其他情况可能有所不同。

main.js

const { spawn } = require('child_process')

console.log('Start Main')

let child = spawn('node', ['child.js'], { detached: true })
child.unref() // With this the main process end after fully disconnect the child

child.stdout.on('data', data => {
  console.log(`Got data : ${data}`)
})

// In real case should be triggered just before the end of the main process
setTimeout(() => {
  console.log('Disconnect the child')

  child.stderr.unpipe()
  child.stderr.destroy()
  child.stdout.unpipe()
  child.stdout.destroy()
  child.stdin.end()
  child.stdin.destroy()
}, 5000)

child.js

console.log('Start Child')

setInterval(function() {
   process.stdout.write('hello from child')
}, 1000)

输出

开始主得到的数据:Start Child

获得数据:来自孩子的问好得到的数据:来自孩子的问好得到的数据:来自孩子的问好得到的数据:来自孩子的问好断开孩子的连接

© www.soinside.com 2019 - 2024. All rights reserved.