2016-10-18 2 views
1

Привет Я использую child_process.spwan для запуска дочернего процесса, выполняющего сценарий python в Windows. Скрипт прослушивает SIGINT, чтобы изящно выйти. Но Windows не поддерживает сигналы, и весь узел имитирует. Так что child_process.kill('SIGINT') на Windows фактически убивает процесс безоговорочно (без изящного выхода, обработчик SIGTERM/SIGINT python не вызывается). Также не работает запись текста ctrl+c на stdin.Nodejs: Отправить Ctrl + C для дочернего процесса в Windows

Когда я просматриваю API-интерфейсы Python, у меня есть 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-минутный тайм-аут, установленный для выхода, если ребенок зависает или подходит к концу.

ру-скрипт-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

Спасибо. Это, безусловно, работает, когда дочерний процесс является узлом. Но что, если в конце концов мне нужно будет порождать процесс Python (например, 'spawn ('python', ['myscript.py']'), который содержит некоторые ресурсы (например, сокеты), но вообще не говорит на Javascript. I IPC-процесс python в кросс-платформенной манере? – kenmark

0

Вы можете отправить команду 'бросить' в процессе Pyhthon, который работал для меня с помощью стандартного ввода , В Python вам нужно создать поток, который считывает из stdin с помощью input, как только это вернется, вы установите флаг события. В вашем основном цикле приложения вы регулярно проверяете, установлено ли событие и выйдет из программы.

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)