如何在Windows上等待Python中的多个子进程,没有主动等待(轮询)?这样的东西几乎适合我:
proc1 = subprocess.Popen(['python','mytest.py']) proc2 = subprocess.Popen(['python','mytest.py']) proc1.wait() print "1 finished" proc2.wait() print "2 finished"
问题是,在proc2
完成之前proc1
,父进程仍将等待proc1
.在Unix上,人们会waitpid(0)
在循环中使用它来完成子进程的返回代码 - 如何在Windows上用Python实现类似的东西?
这似乎有点矫枉过正,但是,这里有:
import Queue, thread, subprocess results= Queue.Queue() def process_waiter(popen, description, que): try: popen.wait() finally: que.put( (description, popen.returncode) ) process_count= 0 proc1= subprocess.Popen( ['python', 'mytest.py'] ) thread.start_new_thread(process_waiter, (proc1, "1 finished", results)) process_count+= 1 proc2= subprocess.Popen( ['python', 'mytest.py'] ) thread.start_new_thread(process_waiter, (proc2, "2 finished", results)) process_count+= 1 # etc while process_count > 0: description, rc= results.get() print "job", description, "ended with rc =", rc process_count-= 1
Twisted有一个异步的进程生成API,适用于Windows.实际上有几种不同的实现,其中许多并不是很好,但您可以在不更改代码的情况下在它们之间切换.
基于zseil的答案,您可以通过混合使用subprocess和win32 API来完成此操作.我使用直接ctypes,因为我的Python没有安装win32api.我现在只是从MSYS中生成sleep.exe作为一个例子,但显然你可以生成任何你喜欢的进程.我使用OpenProcess()从进程'PID获取HANDLE,然后使用WaitForMultipleObjects等待任何进程完成.
import ctypes, subprocess from random import randint SYNCHRONIZE=0x00100000 INFINITE = -1 numprocs = 5 handles = {} for i in xrange(numprocs): sleeptime = randint(5,10) p = subprocess.Popen([r"c:\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, 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] ctypes.windll.kernel32.CloseHandle(h) print "Process %d done" % handles[h] del handles[h] print "All done!"