對於平臺無關的解決方案,我會去與選項#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,您應該能夠通過ctypes
作爲ctypes.windll.kernel32.WaitForMultipleObjects
使用WaitForMultipleObjects
函數,但您必須查看可行性。
對於OSX和Linux,使用signal
模塊異步處理SIGCHLD
可能是最容易的。
一個快速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'
來源
2013-05-02 15:24:41
Aya
什麼操作系統[S]將在需要工作嗎? – Aya 2013-05-02 14:58:20
如果可能的話,主要是Windows,Mac OS X,Linux會很好。最好的將是一個平臺不可知的解決方案。 – Archimedix 2013-05-02 15:53:32
那麼,我給出的答案將適用於Linux和OSX。我將不得不考慮一下Windows解決方案。 – Aya 2013-05-02 15:55:00