Многопоточные инструкции печати Python откладываются до тех пор, пока все потоки не завершат выполнение

У меня есть часть кода ниже, которая создает несколько потоков для выполнения задачи, которая отлично работает сама по себе. Однако я пытаюсь понять, почему заявления печати, которые я вызываю в своей функции, не выполняются до тех пор, пока не будут завершены все потоки и вызывается оператор 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'

Ответ 1

Это происходит из-за буферизации stdout. Вы по-прежнему можете сбросить буферы:

import sys

print 'starting'
sys.stdout.flush()

Вы можете найти дополнительную информацию по этому вопросу здесь и здесь.

Ответ 2

Для python 3 теперь вы можете использовать параметр flush:

print('Your text', flush=True)

Ответ 3

Столкнувшись с множеством проблем, связанных с этим и искаженными выводами (особенно в Windows при добавлении цветов к выводу...), мое решение заключалось в том, чтобы создать эксклюзивный поток печати, который потребляет очередь

Если это по-прежнему не работает, также добавьте flush=True в свои операторы печати, как это было предложено @Or Duan

Кроме того, "наиболее правильный", но неуклюжий подход к отображению с использованием потоков - это, вероятно, использование библиотеки logging

import threading
from queue import Queue

def display_worker(display_queue):
    while True:
        line = display_queue.get()
        if line is None:  # simple termination logic
            break
        print(line)


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()