4

まずは現象を見てみましょう

Nodejs コード:

const cp = require('child_process');

var ls = cp.spawn('ls', ['/']);

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

ls.stderr.on('data', (data) => {
  console.log(`stderr: ${data}`);
});

ls.on('close', (code) => {
  console.log(`child process closed with code ${code}`);
});

while(true){}

このnodejsコードを実行すると、何も表示されず、イベントがトリガーされていないようです。

次に、別のシェルで「ps -ef | grep ls | grpe -v grep」を実行すると、結果は次のようになります。

liyuanq+ 10995 10990  0 11:06 pts/3    00:00:00 [ls] <defunct>

コードを削除する場合:

while(true){}

ノードプロセスが終了し、on data イベントをトリガーしました。

問題は、ノードが実際にジョブを終了したときに、親ノードのプロセスが終了するまで生成されたプロセスを閉じない理由です。

私の環境:

OS: Debian 8.4 x86_64

ノード: v6.1.0

4

1 に答える 1

4

非常に興味深い観察、ありがとう!

子に対して wait() を実行する専用スレッドがある場合、このシナリオは発生しません。

子が終了し、親が wait() を実行する間にギャップがある場合、子はそのギャップ内で機能していないと見なされます。

ノードでは、スレッドが 1 つしかなく、無限ループを実行しているため、イベント ループに入り、子の終了を傍受し、タスク リストから子の ID をクリアする方法はありません。

while-true ループを遅延の長い setTimeout に置き換えると、スレッドは CPU を解放し、子を待機してタスク リストからクリアします。これは確認済みです。

お役に立てれば。

于 2016-06-15T06:07:59.437 に答える