2011-02-17 6 views
5

En python 2.7 en Windows según la documentación, puede enviar un CTRL_C_EVENT (Python 2.7 Subprocess Popen.send_signal documentation). Sin embargo, cuando lo probé no recibí la interrupción del teclado esperada en el subproceso.¿Cómo lograr los resultados deseados al usar los subprocesos Popen.send_signal (CTRL_C_EVENT) en Windows?

Este es el código de ejemplo para el proceso 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) 

Este es el código de ejemplo para el niño proceess:

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

Si corro el parentProcess.py archivo espero obtener "Foo Bar" diez veces luego un "KeyboardInterrupt" seguido por "Foo Bar" 4 veces, pero en su lugar obtengo "Foo Bar" 15 veces.

¿Hay alguna manera de hacer que el CTRL_C_EVENT se comporte como una interrupción de teclado al igual que SIGINT se comporta en Linux?

Después de hacer un poco de lectura me encontré con algo de información que parece Contradic la documentación pitón respecto CTRL_C_EVENT, en particular, se dice que

CTRL_C_EVENT 0 genera una señal CTRL + C. Esta señal no puede ser generada por los grupos de procesos

El siguiente sitio proporcionar más inforamtion acerca de los indicadores de creación: Process Creation Flags.

Respuesta

4

Este método de manejo de señales por subprocesos que funcionó para mí tanto en Linux y Windows 2008, leido, ambos usando Python 2.7.2, pero usa Ctrl-Break en lugar de Ctrl-C. Consulte la nota sobre grupos de procesos y Ctrl-C en 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

Gracias a sherpya de los consejos. –

Cuestiones relacionadas