시작 후 스폰 된 자식 프로세스 분리


9

다음과 같이 스폰 자식 프로세스를 시작합니다.

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

process.unref()

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

프로세스를 시작할 때 출력을 읽고 싶기 때문에 연결 상태를 유지해야합니다. 그러나 Node 프로세스 (부모)를 닫기 직전에 백그라운드에서 계속 실행되도록 완료되지 않은 모든 자식 프로세스를 분리하려고하지만 설명서에 나와 있습니다.

detached 옵션을 사용하여 장기 실행 프로세스를 시작하는 경우, 상위에 연결되지 않은 stdio 구성이 제공되지 않으면 상위 종료 후 프로세스가 백그라운드에서 계속 실행되지 않습니다.

그러나 옵션을 사용 stdio: 'ignore'하면 stdout어느 것이 문제인지 읽을 수 없습니다 .

부모 프로세스를 닫기 전에 파이프를 수동으로 닫으려고했지만 실패했습니다.

// Trigger just before the main process end
process.stdin.end()
process.stderr.unpipe()
process.stdout.unpipe()

1
Node와 독립적 인 프로세스의 stdout / stderr을 읽을 수 있기를 기대하는 이유가 약간 혼란 스럽습니다. 프로세스가 프로그램의 일부인 작업을 수행하고 있기 때문에 출력을 캡처해야합니다.이 경우 노드 상위 여야 합니다. 또는 진정한 독립 프로그램을 시작하는 경우 표준 출력이 Node 프로그램의 관심사가 아니므로 두 개의 독립 프로그램 (예 : 데이터베이스, 파일 모니터, API 서버)에 적합한 방식으로 데이터를 공유해야합니다. )
Mike 'Pomax'Kamermans

프로세스가 시작될 때 출력을 읽고 싶기 때문에 연결 상태를 유지해야합니다. 그러나 Node 프로세스 (부모)를 닫기 직전에 완료되지 않은 모든 자식 프로세스를 분리하여 백그라운드에서 실행되도록하십시오.
반대

다른 프로세스 / 프로그램이없는 이유는 무엇입니까?
Ma'moun othman

파이프가하는 일이 아닙니까? 프로세스 간 통신을 직접 처리하는 것이 좋습니다.
반대

그러나 프로세스를 분리 하시겠습니까? 프로그램 서비스 중 무언가를 수행하고 있습니다.이 경우 프로그램은 완료 될 때까지 기다려야합니다. 또는 프로세스가 시간이 지남에 따라 신호를 보내야합니다. 시그 킬을 받기 직전에 완료해야합니다. : 실제 사용 사례는 무엇입니까? 왜냐하면 이것은 당신이 무언가를 시도 하는 XY 문제 의 주요 후보처럼 들릴 것 입니다. 그리고 당신은 그것을 할 방법을 생각했고, 당신은 원래의 문제에 대해 묻는 대신에 그 일을하는 방법에 대해 묻고 있습니다
Mike 'Pomax'Kamermans

답변:


1

많은 테스트를 거친 후이 문제를 해결하는 적어도 하나의 방법을 찾았습니다. 메인 프로세스를 떠나기 전에 모든 파이프를 파괴하십시오.

한 가지 까다로운 점은 자식 프로세스가 파이프 파괴를 올바르게 처리해야한다는 것입니다. 그렇지 않으면 오류가 발생하여 닫힐 수 있습니다. 이 예제에서 노드 하위 프로세스에는 아무런 문제가없는 것 같지만 다른 시나리오와 다를 수 있습니다.

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)

산출

메인 시작
데이터 : 어린이 시작

있어 데이터 : 안녕하세요 아이로부터
얻었다 데이터 : 안녕하세요 아이로부터
얻었다 데이터 : 안녕하세요 아이에서
아이에서 안녕하세요 :있어 데이터
를 분리 아이

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.