2011-02-17 9 views
5

In python 2.7 in Windows in base alla documentazione è possibile inviare un CTRL_C_EVENT (Python 2.7 Subprocess Popen.send_signal documentation). Tuttavia, quando l'ho provato, non ho ricevuto l'interruzione di tastiera prevista nel sottoprocesso.Come ottenere i risultati desiderati quando si utilizzano le sottosequeste Popen.send_signal (CTRL_C_EVENT) in Windows?

Questo è il codice di esempio per per il processo padre:

# 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) 

Questo è il codice di esempio per la proceess bambino:

# 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" 

Se eseguo il file parentProcess.py mi aspetto di prendi "Foo Bar" dieci volte poi un "KeyboardInterrupt" seguito da "Foo Bar" 4 volte, ma ho invece "Foo Bar" 15 volte.

C'è un modo per ottenere che CTRL_C_EVENT si comporti come un interrupt di tastiera proprio come SIGINT si comporta in Linux?

Dopo aver fatto qualche lettura ho trovato alcune informazioni che sembra contradic la documentazione per quanto riguarda pitone CTRL_C_EVENT, in particolare, si dice che

CTRL_C_EVENT 0 genera un segnale di CTRL + C. Questo segnale non può essere generato per i gruppi di processo

Il seguente sito fornire più inforamtion sui flag di creazione: Process Creation Flags.

risposta

4

Questo metodo di gestione del segnale da sottoprocessi ha funzionato per me sia su Linux e Windows 2008, sia utilizzando Python 2.7.2, ma usa Ctrl-Break invece di Ctrl-C. Vedere la nota sui gruppi di processi e Ctrl-C in 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

Grazie a sherpya per i suggerimenti. –

Problemi correlati