2014-06-30 18 views
7

Tôi đang cố gắng thực hiện hai quy trình hoạt động dài để giao tiếp - một phụ huynh và trẻ em - sử dụng đường ống và mô-đun của Node. Tôi muốn đứa trẻ có thể gửi lại dữ liệu cho phụ huynh một cách không đồng bộ và tôi đã hy vọng sử dụng một số để làm như vậy.Quy trình và đường ống con Node.js - OSX và Ubuntu

Dưới đây là một phiên bản đơn giản hóa của mã của tôi:

phụ huynh:

cp = require('child_process') 
es = require('event-stream') 

child = cp.spawn('coffee', ['child.coffee'], {stdio: [null, null, null, 'pipe']}) 

so = child.stdout.pipe(es.split()) 
p3 = child.stdio[3].pipe(es.split()) 

so.on 'data', (data) -> 
    console.log('stdout: ' + data) 

child.stderr.on 'data', (data) -> 
    console.log('stderr: ' + data); 

p3.on 'data', (data) -> 
    console.log('stdio3: ' + data); 

child.on 'close', (code) -> 
    console.log('child process exited with code ' + code) 

child.stdin.write "a message from your parent", "utf8" 

Child:

fs = require('fs') 

p3 = fs.createWriteStream('/dev/fd/3', {encoding: 'utf8'}) 

process.stdin.on 'data', (data) -> 
    p3.write "hello #{process.pid} - #{data}\n", 'utf8' 
    process.stdout.write "world #{process.pid} - #{data}\n", 'utf8' 
    p3.end() 
    process.exit(0) 

process.stdin.on 'end', (data) -> 
    console.log "end of stdin" 
    p3.end() 
    process.exit(0) 

process.stdin.setEncoding('utf8') 
process.stdin.resume() 

Mã này hoạt động trên OSX 10.9, nhưng không chạy trên một hộp Ubuntu. Tôi đã thử chạy nó dưới cả Ubuntu 12.04 và 14.04. Tôi đang chạy Node 10.2x.

/dev/fd/ dưới Ubuntu được liên kết tượng trưng với /proc/self/fd/ vì vậy tôi tin rằng quy trình con của tôi đang mở tệp phù hợp.

Kết quả từ chạy phụ huynh trên Ubuntu như sau:

$ coffee parent.coffee 
stderr: 

stderr: events.js:72 

stderr:   throw er; // Unhandled 'error' event 

stderr: 
stderr: 
stderr: 
stderr: 
stderr:   ^

stderr: Error: UNKNOWN, open '/dev/fd/3' 




events.js:72 
     throw er; // Unhandled 'error' event 
      ^
Error: read ECONNRESET 
    at errnoException (net.js:901:11) 
    at Pipe.onread (net.js:556:19) 

tôi sẽ mong đợi để xem (và làm trên một hộp OSX):

$ coffee parent.coffee 
stdio3: hello 21101 - a message from your parent 
stdout: world 21101 - a message from your parent 
stdio3: 
stdout: 
child process exited with code 0 

Có thể giao tiếp với đứa trẻ sử dụng dòng lệnh cũng trên Ubuntu, do đó, vấn đề có khả năng xảy ra với cha mẹ khi sinh ra quá trình con:

$ echo foo | coffee child.coffee 3>&1 
hello 3077 - foo 

world 3077 - foo 

Tôi đã cố gắng để điều tra các cuộc gọi hạt nhân mà nút làm cho bằng cách sử dụng , nhưng không thể làm cho nhiều ý nghĩa của đầu ra.

+0

Đầu ra của 'ps aux | grep node' khi cả hai tiến trình đang chạy? – ctlacko

+0

@ChrisLacko Lệnh 'coffee parent.coffee' bị treo ngay lập tức. Trên OSX nó in những gì nó được cho là và sau đó thoát. Tôi có thể thêm các lỗi mà tôi thấy khi tôi chạy nó vào bài đăng. – Jacob

Trả lời

4

Tôi đã tự tìm ra. Lỗi ở trong đứa trẻ. Ubuntu linux là nghiêm ngặt hơn khi nói đến mở các tập tin đã được mở, dòng:

p3 = fs.createWriteStream('/dev/fd/3', {encoding: 'utf8'}) 

đã ném một lỗi. Các mô tả tập tin 3 đã được mở khi trẻ chạy, vì vậy mã nên xem xét như sau:

Child:

fs = require('fs') 

# parent opens the file descriptor 3 when spawning the child (and closes it when the child returns) 
fd3write = (s) -> 
    b = new Buffer(s) 
    fs.writeSync(3,b,0,b.length) 

process.stdin.on 'data', (data) -> 
    fd3write "p3 #{process.pid} - #{data}\n" 
    process.stdout.write "so #{process.pid} - #{data}\n", 'utf8' 
    process.exit(0) 

process.stdin.on 'end', (data) -> 
    console.log "end of stdin" 
    process.exit(0) 

process.stdin.setEncoding('utf8') 
process.stdin.resume() 

Tôi hy vọng điều này sẽ giúp ích cho người khác.

Để sử dụng đường ống thay vì stdin để gửi thư từ cha mẹ đến con, liên kết này có thể được sử dụng: child-process-multiple-file-descriptors.

+0

Bạn cũng có thể đánh dấu các câu trả lời của riêng mình. :) – jgillich

Các vấn đề liên quan