2012-04-25 2 views
0

나는 this guy과 동일한 유스 케이스를 가지고 있으며, 나는 하나의 추가 요구 사항을 제외하고는 this answer을 정말로 좋아한다. 나는 자식 프로세스로부터 리턴 상태를 얻을 필요가있다.Python/Windows/ctypes : WaitForMultipleObjects를 호출 한 후 프로세스 반환 상태를 얻는 방법?

다음은 프로그램 수정에 대한 나의 시도입니다. 나는 윈도우 토지와 파이썬하는 ctypes에서 관광, 그래서 잘하면 내가 바보 아무것도하지 않은 ...

import ctypes, subprocess 
from random import randint 
import os 
SYNCHRONIZE=0x00100000 
PROCESS_QUERY_INFORMATION=0x0400 
INFINITE = -1 
numprocs = 5 
handles = {} 

class Err(BaseException): pass 

for i in xrange(numprocs): 
    sleeptime = randint(5,10) 
    p = subprocess.Popen([r"c:\MinGW\msys\1.0\bin\sleep.exe", str(sleeptime)], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False) 
    h = ctypes.windll.kernel32.OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION, False, p.pid) 
    handles[h] = p.pid 
    print "Spawned Process %d" % p.pid 

while len(handles) > 0: 
    print "Waiting for %d children..." % len(handles) 
    arrtype = ctypes.c_long * len(handles) 
    handle_array = arrtype(*handles.keys()) 
    ret = ctypes.windll.kernel32.WaitForMultipleObjects(len(handle_array), handle_array, False, INFINITE) 
    h = handle_array[ret] 
    print "Process %d done" % handles[h] 
    i = ctypes.c_int(0) 
    pi = ctypes.pointer(i) 
    if ctypes.windll.kernel32.GetExitCodeProcess(h, pi) == 0: 
    err = ctypes.windll.kernel32.GetLastError() 
     raise Err("GetExitCodeProcess: %d" % (err)) 
    print "Status code is: %d" % (i) 
    if ctypes.windll.kernel32.CloseHandle(h) == 0: 
    err = ctypes.windll.kernel32.GetLastError() 
    raise Err("CloseHandle: %d" % (err)) 
    del handles[h] 
print "All done! 

하지만이 프로그램을 실행할 때, 나는 실패 얻을 :

Traceback (most recent call last): 
    File "test.py", line 30, in <module> 
    raise Err("GetExitCodeProcess: %d" % (err)) 
__main__.Err: GetExitCodeProcess: 6 

error 6 is ERROR_INVALID_HANDLE 인 것으로 보입니다. 그러나 핸들이 유효하지 않은 이유는 확실하지 않습니다. PROCESS_QUERY_INFORMATION 권한을 요청했고 CloseHandle() 통화는 GetExitCodeProcess() 전화를 주석 처리하면 올바르게 작동합니다.

아이디어가 있으십니까? 일련의 프로세스를 기다린 후 어떻게 상태 코드를 얻을 수 있습니까? 이 정확한 파이썬 코드 사용

답변

1

(일부 들여 쓰기가 고정 당신과 같은 경로 제거의 Sleep.exe하기) :

C:\tmp\pyt>python -V 
Python 2.7.3 

C:\tmp\pyt>python a.py 
Spawned Process 4368 
Spawned Process 268 
Spawned Process 5792 
Spawned Process 4744 
Spawned Process 4484 
Waiting for 5 children... 
Process 5792 done 
Status code is: 0 
Waiting for 4 children... 
Process 4484 done 
Status code is: 0 
Waiting for 3 children... 
Process 268 done 
Status code is: 0 
Waiting for 2 children... 
Process 4368 done 
Status code is: 0 
Waiting for 1 children... 
Process 4744 done 
Status code is: 0 
All done! 

그래서가 보인다

import ctypes, subprocess 
from random import randint 
import os 
SYNCHRONIZE=0x00100000 
PROCESS_QUERY_INFORMATION=0x0400 
INFINITE = -1 
numprocs = 5 
handles = {} 

class Err(BaseException): pass 

for i in xrange(numprocs): 
    sleeptime = randint(5,10) 
    p = subprocess.Popen([r"sleep.exe", str(sleeptime)], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False) 
    h = ctypes.windll.kernel32.OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION, False, p.pid) 
    handles[h] = p.pid 
    print "Spawned Process %d" % p.pid 

while len(handles) > 0: 
    print "Waiting for %d children..." % len(handles) 
    arrtype = ctypes.c_long * len(handles) 
    handle_array = arrtype(*handles.keys()) 
    ret = ctypes.windll.kernel32.WaitForMultipleObjects(len(handle_array), handle_array, False, INFINITE) 
    h = handle_array[ret] 
    print "Process %d done" % handles[h] 
    i = ctypes.c_int(0) 
    pi = ctypes.pointer(i) 
    if ctypes.windll.kernel32.GetExitCodeProcess(h, pi) == 0: 
     err = ctypes.windll.kernel32.GetLastError() 
     raise Err("GetExitCodeProcess: %d" % (err)) 
    print "Status code is: %d" % i.value 
    if ctypes.windll.kernel32.CloseHandle(h) == 0: 
     err = ctypes.windll.kernel32.GetLastError() 
     raise Err("CloseHandle: %d" % (err)) 
    del handles[h] 

print "All done!" 

날이 출력을 제공합니다 일하고있어. 너의 문제는 다른 곳에서 완전히 다른가? 어떤 OS를 사용하고 있습니까? (광산은 Vista입니까?) Python (2.7.3)의 최신 버전이 있습니까? "sleep.exe"가 어떻게 든 부러지지 않았습니까? 다른 명령을 시도 했습니까?