Python ThreadPoolExecutor: работает не так, как ожидалось?

#python #multithreading

#python #многопоточность

Вопрос:

Согласно realpython:

Завершение блока with заставляет ThreadPoolExecutor выполнять .join() для каждого из потоков в пуле. Настоятельно рекомендуется использовать ThreadPoolExecutor в качестве контекстного менеджера, когда это возможно, чтобы вы никогда не забывали .join() потоков.

 import logging
# import threading
import time
import concurrent.futures

def thread_function(name):
    logging.info("Thread %s: starting", name)
    time.sleep(2)
    logging.info("Thread %s: finishing", name)


if __name__ == "__main__":
    format = "%(asctime)s: %(message)s"
    logging.basicConfig(format=format, level=logging.INFO,
                        datefmt="%H:%M:%S")

    with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
        executor.map(thread_function, range(3))

    print("all done")
 

В данном фрагменте кода я ожидал, что последняя строка — print("all done") будет выполнена в конце (т. Е. После завершения выполнения всех потоков). Однако это не так? чего мне не хватает?

Комментарии:

1. На моей машине print("all done") оператор выполнялся последним, как и ожидалось.

2. @daktoad Попробуйте несколько раз, и вы увидите результат, подобный этому pastebin.com/fyC9EqQk

3. Это интересно. Я только что попробовал это на другой машине несколько раз, и все по-прежнему непротиворечиво. Вы используете это в Windows?

4. @daktoad Я на Linux, вот снимок экрана вывода imgur.com/a/lh6ex27

Ответ №1:

Я думаю, это как-то связано с тем, как выводятся буферы консоли Pycharm (которые вы показали на своем скриншоте).

Я запускал его несколько раз в pycharm, и иногда он работал, а в других случаях не работал. Однако, когда вы запускаете его в терминале (или указываете pycharm «эмулировать вывод терминала») Я больше этого не вижу

Комментарии:

1. Да, это то, что происходит.