【问题标题】:Python multithreaded print statements delayed until all threads complete executionPython多线程打印语句延迟到所有线程完成执行
【发布时间】:2013-08-16 13:36:40
【问题描述】:

我在下面有一段代码,它创建了几个线程来执行任务,它本身就可以很好地工作。但是,我很难理解为什么我在函数中调用的打印语句在所有线程完成并调用 print 'finished' 语句之前不会执行。我希望它们在线程执行时被调用。有没有什么简单的方法可以做到这一点,为什么首先要这样做?

def func(param):
    time.sleep(.25)
    print param*2

if __name__ == '__main__':
    print 'starting execution'
    launchTime = time.clock()
    params = range(10)
    pool=multiprocessing.Pool(processes=100) #use N processes to download the data
    _=pool.map(func,params)
    print 'finished'

【问题讨论】:

  • 只是想我会指出这是duplicate 在 SO 上提出的另一个(未回答的)问题,但不那么混乱。
  • 您的意思是,所有打印件同时进行,还是它们的预期顺序实际上颠倒了?如果它们一次全部运行,则可能是系统缓冲。如果顺序颠倒,那就更有趣了。
  • 实际上两者兼而有之。打印 'finshed' 后,打印语句会立即发生。

标签: python multithreading


【解决方案1】:

这是由于标准输出缓冲而发生的。您仍然可以刷新缓冲区:

import sys

print 'starting'
sys.stdout.flush()

您可以在herehere 找到有关此问题的更多信息。

【讨论】:

  • 我相信缓冲不应该改变预期的打印顺序。
  • 经过测试。在 print 语句之后添加 sys.stdout.flush() 都会导致它们在“完成”之前输出,并在每个单独的线程完成时打印,而不是等到结束。另外,它是一个非常干净的解决方案!接受。
  • 这对我不起作用 :( 。看起来我的打印队列无法处理
【解决方案2】:

对于 python 3,您现在可以像这样使用 flush 参数:

print('Your text', flush=True)

【讨论】:

    【解决方案3】:

    遇到了很多与此相关的问题和输出乱码(尤其是在 Windows 下向输出添加颜色时..),我的解决方案是拥有一个消耗队列的专用打印线程

    如果此仍然不起作用,请按照 @Or Duan

    的建议将flush=True 添加到您的打印语句中

    此外,您可能会发现“最正确”的方法,但是使用线程显示消息的一种强硬方法是使用 logging 库,该库可以 wrap a queue(并异步写入许多地方,包括标准输出)或write to a system-level queue(Python 之外;可用性很大程度上取决于操作系统支持)

    import threading
    from queue import Queue
    
    def display_worker(display_queue):
        while True:
            line = display_queue.get()
            if line is None:  # simple termination logic, other sentinels can be used
                break
            print(line, flush=True)  # remove flush if slow or using Python2
    
    
    def some_other_worker(display_queue, other_args):
        # NOTE accepts queue reference as an argument, though it could be a global
        display_queue.put("something which should be printed from this thread")
    
    
    def main():
        display_queue = Queue()  # synchronizes console output
        screen_printing_thread = threading.Thread(
            target=display_worker,
            args=(display_queue,),
        )
        screen_printing_thread.start()
    
        ### other logic ###
    
        display_queue.put(None)  # end screen_printing_thread
        screen_printing_thread.stop()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-05
      相关资源
      最近更新 更多