2014-09-26 4 views
1

Я использую Node.js v0.10.31 для Windows 8.1 x64. Я заметил, что для процесса (сценария node.js или python), который обрабатывает обработчик SIGINT, обработчик не вызывается, когда сигнал отправляется из другого процесса node.js на process.kill(PID, "SIGINT") и, таким образом, вызывает его завершение. Однако я действительно подтвердил, что обработчики вызываются, если SIGINT отправляется нажатием CTRL-C в консоли.Node.js: SIGINT, отправленный с process.kill() не может быть обработан

Вот сценарий Node.js, который обрабатывает SIGINT (CoffeeScript):

process.on 'SIGINT', -> console.log "SIGINT handled" 
process.stdin.pipe(process.stdout) 
console.log "PID: #{process.pid}" 

Консоли вывод:

PID: 6916 
SIGINT handled  (this happens when pressing ctrl-c in console) 
SIGINT handled  (this happens when pressing ctrl-c in console) 
# process terminates when another process calls process.kill(6916, 'SIGINT') 

А вот питон скрипт, который обрабатывает SIGINT, который также убит безусловно узел .js process.kill(PID, 'SIGINT'):

from signal import signal, SIGINT 
import os 
import time 

def handler(signum, frame): 
    print "signal handled:", signum, 
    raise KeyboardInterrupt 

signal(SIGINT, handler) 

print "PID: ", os.getpid() 
while True: 
    try: 
     time.sleep(1e6) 
    except KeyboardInterrupt: 
     print " KeyboardInterrupt handled" 

Консольный выход:

PID: 6440 
signal handled:2 KeyboardInterrupt handled (this happens when pressing ctrl-c in console) 
signal handled:2 KeyboardInterrupt handled (this happens when pressing ctrl-c in console) 
# process terminated by another node.js script's process.kill(6440, 'SIGINT') 

Почему не называется обработчик?

ответ

1

Похоже, что это не проблема Node.js, которая отправляет SIGINT, а скорее проблему с платформой Windows. Это потому, что когда я посылаю SIGINT из программы питона, он также безоговорочно завершает процесс, который обрабатывает событие SIGINT:

os.kill(pid, signal.SIGINT) 

К счастью, Python документирует это лучше:

os.kill (ИДП, сиг)

Отправка сигнала sig в ​​процесс pid. Константы для конкретные сигналы, доступные на платформе хоста, определены в сигнальном модуле .

окно: signal.CTRL_C_EVENT и signal.CTRL_BREAK_EVENT сигналы специальные сигналы, которые могут быть направлены только на консоль процессов, которые разделяет общее окно консоли, например, некоторые подпроцессы. Любое другое значение для sig приведет к тому, что процесс будет безоговорочно убит API TerminateProcess, а код выхода будет установлен на sig. Windows-версия kill() дополнительно обрабатывает дескрипторы процесса убит.

+0

Основная проблема ИМО заключается в том, что Node.js и Python пытаются притвориться, что сигналы являются универсальной концепцией, а не конкретными конкретными операционными системами. Вероятно, разработчик будет менее запутанным, если связанные с сигналом функции просто не существуют в версии Windows, а не существуют, но не ведут себя так, как ожидалось. –

+0

@HarryJohnston Signals (по крайней мере, SIGINT и некоторые другие) _are_ универсальная концепция. Они [определены в стандартной библиотеке C] (https://en.wikipedia.org/wiki/C_signal_handling) и должны поддерживаться любой формой plaft. – KFL

+0

Сигналы C и сигналы UNIX на самом деле не то же самое. В частности, стандарт C не требует какой-либо поддержки для отправки сигналов между процессами, и, действительно, реализация Visual Studio не позволяет этого сделать.(В UNIX сигналы C реализуются с использованием сигналов UNIX, а исторически сигналы C были получены из сигналов UNIX, но концептуально они различны.) –