2016-10-18 10 views
1

こんにちは私はchild_process.spwanを使ってWindows上でPythonスクリプトを実行している子プロセスを開始しています。スクリプトはSIGINTを待ち受けて正常に終了します。しかし、Windowsはシグナルをサポートしておらず、すべてのノードがシミュレーションしていました。したがって、Windows上のchild_process.kill('SIGINT')は、実際に無条件にプロセスを強制終了しています(優雅な終了、pythonのSIGTERM/SIGINTハンドラは呼び出されません)。また、ctrl+c文字をstdinに書き込むこともできません。Nodejs:Windows上の子プロセスにCtrl + Cを送信

私はPython APIを調べると、必要に応じてCTRL_BREAK_EVENTとCTRL_C_EVENTを取得しました。私はノードがこれらのようなプラットフォーム固有のAPIを持っているのだろうか?

関連の記事ではなく、作業のもの: How to send control C node.js and child_processes sending crtl+c to a node.js spawned childprocess using stdin.write()?

答えて

1

あなたは、その時間は停止し、正常に終了する子供に知らせるためにIPCメッセージを使用することができます。以下の方法では、process.on('message')を使用して、子プロセス& child_process.send()の親からのメッセージを受信し、親から子へメッセージを送信します。

子供がハングアップしたり終了するまでに時間がかかる場合、以下のコードでは1分のタイムアウトが設定されています。

PY-スクリプトwrapper.js

// Handle messages sent from the Parent 
process.on('message', (msg) => { 
    if (msg.action === 'STOP') { 
    // Execute Graceful Termination code 
    process.exit(0); // Exit Process with no Errors 
    } 
}); 

親プロセス

const cp = require('child_process'); 
const py = cp.fork('./py-script-wrapper.js'); 

// On 'SIGINT' 
process.on('SIGINT',() => { 
    // Send a message to the python script 
    py.send({ action: 'STOP' }); 

    // Now that the child process has gracefully terminated 
    // exit parent process without error 
    py.on('exit', (code, signal) => { 
    process.exit(0); 
    }); 

    // If the child took too long to exit 
    // Kill the child, and exit with a failure code 
    setTimeout(60000,() => { 
    py.kill(); 
    process.exit(1); 
    }); 

}); 
+1

感謝。これは確かに、子プロセスがノードプロセスである場合に機能します。しかし、結局のところ、いくつかのリソース(ソケットなど)を保持するが、JavaScriptをまったく話さないPythonプロセス(例えば、 'spawn( 'python'、['myscript.py']')を生成する必要があればどうでしょうか。私は、クロスプラットフォームの方法でPythonのprocをIPCするのですか? – kenmark

0
あなたは私のために働いPyhthonプロセスに標準入力を経由して '終了' コマンドを送ることができ

。 Pythonでは、inputを使用してstdinから読み込むスレッドを作成する必要があります。これが戻ったら、イベントフラグを設定します。メインのアプリケーションループでは、定期的にイベントが設定されているかどうかをチェックし、プログラムを終了します。

Pythonアプリケーション(script.py):

import threading 
import sys 

def quit_watch(event): 
    input("Type enter to quit") 
    event.set() 

def main(): 
    stop = threading.Event() 
    threading.Thread(target=quit_watch, args=[stop]).start() 

    while True: 
     # do work, regularly check if stop is set 
     if stop.wait(1): 
      print("Stopping application loop") 
      break 

if __name__ == '__main__': 
    main() 
    sys.exit(0) 

のNode.jsアプリケーション:

child_process = require('child_process') 
child = child_process.spawn('python.exe', ['script.py']) 
// check if process is still running 
assert(child.kill(0) == true) 
// to terminate gracefully, write newline to stdin 
child.stdin.write('\n') 
// check if process terminated itself 
assert(child.kill(0) == false) 
関連する問題