2011-02-17 10 views
5

W pythonie 2.7 w oknach zgodnie z dokumentacją można wysłać CTRL_C_EVENT (Python 2.7 Subprocess Popen.send_signal documentation). Jednak gdy spróbowałem, nie otrzymałem oczekiwanego przerwania klawiatury w podprocesie.Jak osiągnąć pożądane rezultaty podczas korzystania z podprocesów Popen.send_signal (CTRL_C_EVENT) w systemie Windows?

To jest przykładowy kod dla procesu nadrzędnego:

# FILE : parentProcess.py 
import subprocess 
import time 
import signal 

CREATE_NEW_PROCESS_GROUP = 512 
process = subprocess.Popen(['python', '-u', 'childProcess.py'], 
         stdin=subprocess.PIPE, 
         stdout=subprocess.PIPE, 
         stderr=subprocess.STDOUT, 
         universal_newlines=True, 
         creationflags=CREATE_NEW_PROCESS_GROUP) 
print "pid = ", process.pid 
index = 0 
maxLoops = 15 
while index < maxLoops: 
    index += 1 
    # Send one message every 0.5 seconds 
    time.sleep(0.5) 
    # Send data to the subprocess 
    process.stdin.write('Bar\n') 
    # Read data from the subprocess 
    temp = process.stdout.readline() 
    print temp, 
    if (index == 10): 
     # Send Keyboard Interrupt 
     process.send_signal(signal.CTRL_C_EVENT) 

To jest przykładowy kod dla proceess dzieci:

# FILE : childProcess.py 
import sys 

while True: 
    try: 
     # Get data from main process 
     temp = sys.stdin.readline() 
     # Write data out 
     print 'Foo ' + temp, 
    except KeyboardInterrupt: 
     print "KeyboardInterrupt" 

Jeśli uruchomię parentProcess.py plików Spodziewam dostać "Foo Bar" dziesięć razy, potem "KeyboardInterrupt", a następnie "Foo Bar" 4 razy, ale zamiast tego otrzymuję "Foo Bar" 15 razy.

Czy istnieje sposób, aby CTRL_C_EVENT zachowywał się jak przerywanie klawiatury, tak jak SIGINT zachowuje się w systemie Linux?

Po jakiejś lektury znalazłem pewne informacje, które wydaje się contradic dokumentacji Pythona dotyczące CTRL_C_EVENT, w szczególności mówi, że

CTRL_C_EVENT 0 generuje sygnał CTRL + C. Sygnał ten nie może być generowany dla grup procesów

Poniższa strona dostarczają więcej inforamtion o flagi utworzenia: Process Creation Flags.

Odpowiedz

4

Ten sposób obsługi sygnału przez podprocesów pracował dla mnie zarówno na Linux i Windows 2008, zarówno przy użyciu Python 2.7.2, ale używa Ctrl-Break zamiast Ctrl-C. Zobacz notatkę dotyczącą grup procesów i Ctrl-C w http://msdn.microsoft.com/en-us/library/ms683155%28v=vs.85%29.aspx.

catcher.py:

import os 
import signal 
import sys 
import time 

def signal_handler(signal, frame): 
    print 'catcher: signal %d received!' % signal 
    raise Exception('catcher: i am done') 

if hasattr(os.sys, 'winver'): 
    signal.signal(signal.SIGBREAK, signal_handler) 
else: 
    signal.signal(signal.SIGTERM, signal_handler) 

print 'catcher: started' 
try: 
    while(True): 
     print 'catcher: sleeping...' 
     time.sleep(1) 
except Exception as ex: 
    print ex 
    sys.exit(0) 

thrower.py:

import signal 
import subprocess 
import time 
import os 

args = [ 
    'python', 
    'catcher.py', 
    ] 
print 'thrower: starting catcher' 
if hasattr(os.sys, 'winver'): 
    process = subprocess.Popen(args, creationflags=subprocess.CREATE_NEW_PROCESS_GROUP) 
else: 
    process = subprocess.Popen(args) 

print 'thrower: waiting a couple of seconds for catcher to start...' 
time.sleep(2) 
print 'thrower: sending signal to catch' 

if hasattr(os.sys, 'winver'): 
    os.kill(process.pid, signal.CTRL_BREAK_EVENT) 
else: 
    process.send_signal(signal.SIGTERM) 

print 'thrower: i am done' 
+0

Dzięki sherpya za podpowiedzi. –

Powiązane problemy