Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 确保线程上次执行工作_Python_Multithreading_Subprocess - Fatal编程技术网

Python 确保线程上次执行工作

Python 确保线程上次执行工作,python,multithreading,subprocess,Python,Multithreading,Subprocess,最后,我能够生成多个子进程,并使用线程将它们的stdout实时导入python 我有一个dict列表,其中包含生成子进程和从管道读取的线程所需的所有数据结构。我想要运行的特定程序需要几个小时才能完成,因此我可以接受这样一个事实,即标准输出仅每4096字节刷新一次 下面是一些精简的代码: from time import sleep import subprocess from threading import Thread from Queue import Queue, Empty def

最后,我能够生成多个子进程,并使用线程将它们的stdout实时导入python

我有一个dict列表,其中包含生成子进程和从管道读取的线程所需的所有数据结构。我想要运行的特定程序需要几个小时才能完成,因此我可以接受这样一个事实,即标准输出仅每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(工作列表中的项['pid'].poll()不是None)
是真的。在stdout管道中仍然可能有一些我的线程尚未读取的信息。
我的破解方法是在所有子进程完成后等待10秒,然后最后运行一次循环。这可能永远不会导致任何问题,但我真的不喜欢这种方式,我想知道是否可以进行真正的修复,以便在子进程完成后,我的线程被迫再次读取

你就不能
join()
每个线程吗?怎么会这样?即使子进程已经完成,线程也不会继续它的工作(例如,从我管道中的标准输出读取)。对,线程将继续工作,直到它从
out.readline
获得EOF,这是您想要的,不是吗?只有在十秒钟睡眠后调用
work['pid'].wait()
时,才会刷新标准输出缓冲区吗?如果你只做
睡眠
,它能工作吗?或者只需执行
等待
?如果调用
work['pid'].stdout.flush()
,会怎么样?我没有意识到我的stdout会生成EOF。标准输出缓冲区每4096字节刷新一次,并在程序退出时刷新一次。在它上面调用stdout.flush()没有什么区别,因为windows会缓冲它。。。我的等待只是为了让线程能够完成阅读。但如果生成EOF,我确实可以使用.join()`