python - Hvordan opnår du ønskede resultater, når du bruger underprocesserne Popen.send\_signal (CTRL\_C\_EVENT) i Windows?

Indlæg af Hanne Mølgaard Plasc

Problem



I python 2,7 i windows ifølge dokumentationen kan du sende en CTRL\_C\_EVENT
(Python 2.7 Subprocess Popen.send\_signal dokumentation).
Men da jeg prøvede det, fik jeg ikke den forventede tastaturafbrydelse i underprocessen. [7]


Dette er eksemplet kode for for overordnet proces:


# 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
')
    # Read data from the subprocess
    temp = process.stdout.readline()
    print temp,
    if (index == 10):
        # Send Keyboard Interrupt
        process.send\_signal(signal.CTRL\_C\_EVENT)


Dette er prøvekoden til børneprocessen:


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


Hvis jeg kører filen parentProcess.py Jeg forventer at få 'Foo Bar' ti gange så en 'KeyboardInterrupt' efterfulgt af 'Foo Bar' 4 gange, men jeg får 'Foo Bar' 15 gange i stedet.


Er der en måde at få CTRL\_C\_EVENT til at opføre sig som et tastatur afbrydelser, ligesom SIGINT opfører sig i Linux?


Efter lidt læsning fandt jeg nogle oplysninger, der synes at være i modstrid med python-dokumentationen vedrørende CTRL\_C\_EVENT, især det siger at



  CTRL\_C\_EVENT
  0 Genererer et CTRL + C signal. Dette signal kan ikke genereres for procesgrupper



Følgende websted giver mere information om oprettelse af flag:
Process Creation Flags. [8]

Bedste reference


Denne metode til signalhåndtering ved delprocesser fungerede for mig på både Linux og Windows 2008, begge med Python 2.7.2, men det bruger Ctrl-Break i stedet for Ctrl-C. Se noten om procesgrupper og Ctrl-C på http://msdn.microsoft.com/en-us/library/ms683155\%28v=vs.85\%29.aspx.[9]


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'

Andre referencer 1


prøv med


win32api.GenerateConsoleCtrlEvent(CTRL\_C\_EVENT, pgroupid)


eller


win32api.GenerateConsoleCtrlEvent(CTRL\_BREAK\_EVENT, pgroupid)


referencer:


http://docs.activestate.com/activepython/2.5/pywin3/win32process\_CREATE\_NEW\_PROCESS\_GROUP.html[10]


http://msdn.microsoft.com/en-us/library/ms683155\%28v=vs.85\%29.aspx[11]


læs info om dwProcessGroupId, groupid skal være den samme af proces id