为了向自己证明一个概念,我写了这段代码:
from subprocess import Popen, PIPE
import json
queue = []
command1 = ['python', 'C:\Desktop\testing_popen\time_delay.py']
command2 = ['python', 'C:\Desktop\testing_popen\no_time_delay.py']
queue.append(Popen(command1, stdout=PIPE))
queue.append(Popen(command2, stdout=PIPE))
while len(queue) > 0:
while queue[0].poll() is None:
queue.append(queue.pop(0))
print json.loads(queue.pop(0).communicate()[0])
no_time_delay.py的输出
从time_delay.py输出
这完全按照我的意愿工作,因此队列中的元素不会被阻挡,但是更接近前面的元素需要更长的处理时间。我正在使用队列作为限制进程的一种方式,这样我就不会耗尽所有的CPU,但我总是希望运行最多的进程数。
然后我想在项目中实现这个
我必须处理200条记录,但我只想要一次运行10个脚本,以免CPU过载。每个脚本只能处理10条记录。
所以..
我创建了一个队列并
while len(scripts_to_be_processed) > 0:
if len(queue) < 10:
queue.append(Popen(command,stdout=PIPE,stderr=PIPE))
else:
while queue[0].poll() is None:
queue.append(queue.pop(0))
function_to_process_out(queue.pop(0).communicate()[0])
然后处理此循环之外的队列中剩余的脚本..
该过程涉及摄取xlsx文件,我可以从我的任务管理器看到进程已经完成但协调实例的主脚本仅从轮询中接收到无。
我已经更新了脚本,以便在运行结束时将输出写入文件。该文件将在std.out.write之前写入,但之后不会写入,因此我的理论是常量轮询可能会阻止脚本输出。
非常感谢任何帮助,
干杯
修改
更新:我的问题在于使用PIPE作为我的标准输出。缓冲区文件已填满并导致死锁。我通过使用换行符分隔符将每个单独的记录写入stdout来修复此问题,并为每个子进程创建一个线程,通过调用.readline()来监听每个子进程的stdout。这使我可以不断清空临时缓冲区文件并避免死锁。