对于与平台无关的解决方案,我会选择选项 #2,因为高 CPU 使用率的“CON”可以通过类似...
import time
# Assuming the Popen objects are in the dictionary values
PROCESS_DICT = { ... }
def my_thread_main():
while 1:
dead_keys = []
for k, v in PROCESS_DICT.iteritems():
v.poll()
if v.returncode is not None:
dead_keys.append(k)
if not dead_keys:
time.sleep(1) # Adjust sleep time to taste
continue
for k in dead_keys:
del PROCESS_DICT[k]
...因此,如果没有进程在迭代中死亡,您只需睡一会儿。
因此,实际上,您的线程大部分时间仍然处于休眠状态,尽管在子进程死亡与其随后的“清理”之间存在潜在的延迟,但这真的没什么大不了的,这应该比每次使用一个线程更好地扩展过程。
但是,有更好的平台相关解决方案。
对于 Windows,您应该可以通过as使用该WaitForMultipleObjects
功能,尽管您必须研究其可行性。ctypes
ctypes.windll.kernel32.WaitForMultipleObjects
对于 OSX 和 Linux,使用模块SIGCHLD
异步处理可能是最简单的。signal
一个快速n'肮脏的例子......
import os
import time
import signal
import subprocess
# Map child PID to Popen object
SUBPROCESSES = {}
# Define handler
def handle_sigchld(signum, frame):
pid = os.wait()[0]
print 'Subprocess PID=%d ended' % pid
del SUBPROCESSES[pid]
# Handle SIGCHLD
signal.signal(signal.SIGCHLD, handle_sigchld)
# Spawn a couple of subprocesses
p1 = subprocess.Popen(['sleep', '1'])
SUBPROCESSES[p1.pid] = p1
p2 = subprocess.Popen(['sleep', '2'])
SUBPROCESSES[p2.pid] = p2
# Wait for all subprocesses to die
while SUBPROCESSES:
print 'tick'
time.sleep(1)
# Done
print 'All subprocesses died'