确保线程上次执行工作

时间:2014-06-16 19:48:59

标签: python multithreading subprocess

最后,我能够使用线程生成多个子进程并将其stdout实时地发送到python中。

我有一个dicts列表,其中包含生成子进程所需的所有数据结构以及从管道中读取的线程。我想运行的特定程序需要几个小时才能完成,所以我可以忍受stdout每4096字节只刷一次的事实。

所以这是一些剥离的代码:

from time import sleep
import subprocess
from threading import Thread
from Queue import Queue, Empty

def enqueue_output(out, queue):
    for line in iter(out.readline, b''):
        queue.put(line)
    out.close()

def queue_get_all(queue):   
    items = [] 
    while True:
        try:
            items.append(queue.get_nowait())
        except Empty, e:
            break
    return items

worklist=[
    {
        'cmd'     :r'command 1',
        'pid'     :None,
        'queue'   :None,
        'thread'  :None
    },{
        'cmd'     :r'command 2',
        'pid'     :None,
        'queue'   :None,
        'thread'  :None
    },{
        'cmd'     :r'command 3',
        'pid'     :None,
        'queue'   :None,
        'thread'  :None
    }
]


for work in worklist:
    work['pid'] = subprocess.Popen(work['cmd'], stdout=subprocess.PIPE, stderr=subprocess.PIPE,bufsize=0)
    work['queue'] = Queue()
    work['thread'] = Thread(target=enqueue_output, args=(work['pid'].stdout, work['queue']))
    work['thread'].daemon = True
    work['thread'].start()


finalflush = False
while True:
    for work in worklist:
        lines = queue_get_all(work['queue'])
        for line in lines:
            print line

    if all(item['pid'].poll() is not None for item in worklist):
        if finalflush == False:
            sleep(10)
            finalflush = True
            continue
        else:
            break

for work in worklist:
    work['pid'].wait()

所以我面临的问题是,一旦所有流程完成,因此all(item['pid'].poll() is not None for item in worklist)为真。 stdout管道中仍然可能存在一些尚未被我的线程读取的信息。 我的修复是在所有子进程完成后等待10秒,然后最后一次运行循环。这可能不会导致任何问题,但我不是那么喜欢它,我想知道我是否可以做一个真正的修复,所以我的线程被迫在子进程完成后再次读取!

0 个答案:

没有答案