2014-06-30 41 views
7

İki büyük koşu işlemlerini, bir ebeveyn ve bir çocuk - borular ve Düğümün modülünü kullanarak iletmeye çalışıyorum. Çocuğun veriyi asenkronize olarak tekrar ebeveyne göndermesini istiyorum ve bunu yapmak için kullanmayı umuyordum.Node.js çocuk süreçleri ve boruları - OSX vs Ubuntu

İşte benim kod basitleştirilmiş versiyonu:

Veli:

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" 

Çocuk:

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() 

kod OSX 10.9 üzerinde çalışır, ancak bir Ubuntu kutuyu çalıştırmak için başarısız olur. Ubuntu 12.04 ve 14.04'ün altında çalıştırmayı denedim. Düğüm 10.2x çalıştırıyorum. Ubuntu'nun altında /dev/fd/ , /proc/self/fd/ sembolik olarak bağlantılıdır, bu yüzden çocuk sürecimin doğru dosyayı açtığına inanıyorum.

şöyle Ubuntu üzerinde ebeveyn çalışan çıktısı şu şekildedir:

$ 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) 
görüyorum (ve bir OSX kutuyu yapmak) beklenir

:

iletişim kurmak mümkündür
$ 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 

Komut satırını Ubuntu'da da kullanan çocuk, bu nedenle sorun, alt işlemin üstesinden geldiğinde büyük olasılıkla üst sıradadır:

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

world 3077 - foo 

Düğümün, 'u kullandığı çekirdek çağrılarını araştırmaya çalıştım, ancak çıktıyı çok fazla anlamamıştım.

+0

'ps aux'nin çıktısı nedir | Her iki süreç çalışırken grep düğümü – ctlacko

+0

@ChrisLacko "Kahve parent.coffee" komutu hemen çöker. OSX'de, ne gerekiyorsa ve sonra çıkar. Gördüğüm hataları gönderiye ekleyebilirim. – Jacob

cevap

4

Kendim anladım. Hata çocuktu.

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

bir hata atma edildi: o, çizgi zaten açık olan dosyaları açma konusunda Ubuntu linux daha sıkı. çocuk çalıştırdığında dosya tanımlayıcı 3 zaten açık, bu nedenle görünmelidir kod aşağıda:

Çocuk:

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() 

bu başkasına yardım olacağını umuyoruz.

Ebeveynten çocuğa ileti göndermek için yerine bir boru kullanmak için şu bağlantı kullanılabilir: child-process-multiple-file-descriptors.

+0

Kendi cevaplarınızı da kabul edildi olarak işaretleyebilirsiniz. :) – jgillich