Tách một quá trình sinh sản con sau khi bắt đầu


9

Tôi bắt đầu một đứa trẻ sinh sản xử lý theo cách này:

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

process.unref()

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

Khi tôi bắt đầu quá trình tôi cần phải giữ nó bởi vì tôi muốn đọc đầu ra của nó. Nhưng ngay trước khi đóng quy trình Node của tôi (cha mẹ), tôi muốn tách tất cả các tiến trình con chưa hoàn thành để giữ cho chúng chạy ở chế độ nền, nhưng như tài liệu nói:

Khi sử dụng tùy chọn tách rời để bắt đầu một quy trình chạy dài, quy trình sẽ không chạy trong nền sau khi cha mẹ thoát ra trừ khi được cung cấp cấu hình stdio không được kết nối với cha mẹ.

Nhưng với tùy chọn stdio: 'ignore'tôi không thể đọc được stdoutđó là một vấn đề.

Tôi đã cố gắng tự đóng các đường ống trước đó để đóng quy trình cha mẹ nhưng không thành công:

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

1
Tôi hơi bối rối tại sao bạn mong đợi có thể đọc stdout / stderr của một quá trình độc lập với Node. Bạn cần phải nắm bắt đầu ra, bởi vì quá trình đang thực hiện các tác vụ là một phần của chương trình của bạn (chỉ chạy song song) trong trường hợp Node phải là cha mẹ; hoặc bạn đang bắt đầu một chương trình thực sự độc lập, trong trường hợp đầu ra tiêu chuẩn của nó không phải là mối quan tâm của chương trình Node của bạn và bạn nên làm cho chúng chia sẻ dữ liệu theo cách hợp lý cho hai chương trình độc lập (ví dụ: cơ sở dữ liệu, trình giám sát tệp, máy chủ API , bất cứ điều gì).
Mike 'Pomax' Kamermans

Có lẽ tôi đã không đủ rõ ràng, khi tôi bắt đầu quá trình tôi cần phải giữ nó bởi vì tôi muốn đọc đầu ra của nó. Nhưng ngay trước khi đóng quá trình Node của tôi (cha mẹ), tôi muốn tách tất cả các tiến trình con chưa hoàn thành để giữ cho chúng chạy ở chế độ nền.
Opsse

Tại sao không có các quy trình / chương trình khác nhau và chia sẻ dữ liệu giữa chúng bằng cách sử dụng một tệp hoặc một số ý nghĩa khác.
Ma'moun othman

Đó không phải là những gì một đường ống làm gì? Vì vậy, bạn đề nghị để tự xử lý giao tiếp giữa các quá trình?
Opsse

Nhưng tại sao bạn lại tách ra quá trình? Hoặc là nó đang làm gì đó để phục vụ cho chương trình của bạn, trong trường hợp đó, chương trình của bạn sẽ đợi cho đến khi hoàn thành hoặc nó sẽ báo hiệu quá trình đã hết thời gian và cần hoàn thành những gì nó đang làm vì sắp có SIGKILL'd - Về cơ bản : trường hợp sử dụng thực tế là gì? Bởi vì điều này nghe có vẻ như là một ứng cử viên chính cho vấn đề XY khi bạn đang cố gắng làm điều gì đó và bạn đã nghĩ ra một cách để làm điều đó và bạn đang hỏi về cách làm việc đó thay vì hỏi về vấn đề ban đầu
Mike 'Pomax' Kamermans

Câu trả lời:


1

Sau nhiều thử nghiệm, tôi đã tìm thấy ít nhất một cách để giải quyết vấn đề này: phá hủy tất cả các đường ống trước khi rời khỏi quy trình chính.

Một điểm khó khăn là quy trình con phải xử lý chính xác các đường ống phá hủy, nếu không nó có thể bị lỗi và đóng lại. Trong ví dụ này, quá trình con nút dường như không có vấn đề gì với điều này nhưng nó có thể khác với kịch bản khác.

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)

đầu ra

Bắt đầu
dữ liệu chính Có: Bắt đầu con

Có dữ liệu: xin chào từ trẻ
Có dữ liệu: xin chào từ trẻ
Có dữ liệu: xin chào từ trẻ
Có dữ liệu: xin chào từ trẻ
Ngắt kết nối trẻ

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.