Почему concurrent.futures 'submit () сразу не возвращает управление основной программе? - PullRequest
0 голосов
/ 08 ноября 2019

Я изучаю concurrent.futures (переход от threading), и мне не удается понять, как именно работает отправка и ожидание.

Рассмотрим следующий код: запущены два потока, один из которых предположительнонемедленно завершается, в то время как другой зависает на неопределенный срок.

Я ожидал, что оба потока будут отслеживаться через submit(), и управление немедленно возвращается основной программе.

После этого wait() с таймаутом вернет кортеж из потоков done и not_done (not_done будет принудительно прерван из-за таймаута).

import concurrent.futures
import time

def worker(wait_infinite):
    if wait_infinite:
        time.sleep(100)

with concurrent.futures.ThreadPoolExecutor() as executor:
    inf = executor.submit(worker, True)
    not_inf = executor.submit(worker, False)

res = concurrent.futures.wait([inf, not_inf], timeout=2)
print(res)

В результате происходит зависание выполнения not_inf = executor.submit(worker, False). Почему управление не возвращается основной программе?

1 Ответ

1 голос
/ 08 ноября 2019

В конце выполнения оператора with вызывается executor.shutdown. Ожидание всех потоков, чтобы закончить. Вы должны переместить wait в оператор with, Затем вызвать executor.shutdown(False), чтобы прекратить ожидание зависшего потока. (правка: вы не можете корректно отменить запущенный поток, если только он не находится в кооперативном режиме или если он не находится вдругой процесс https://stackoverflow.com/a/55351671/7284763)

источник

executor.shutdown (wait = True)

Сигнализирует исполнителя, что он должен освободить любойресурсы, которые он использует, когда выполняются> ожидающие в настоящее время фьючерсы. Вызовы Executor.submit () и> Executor.map (), сделанные после завершения работы, вызовут RuntimeError.

Если wait равно True, тогда этот метод будетне возвращать, пока все ожидающие фьючерсы не будут выполнены, и ресурсы, связанные с исполнителем, будут освобождены. Если wait - False, то этот метод вернется немедленно, и ресурсы, связанные с исполнителем, будут освобождены, когда все ожидающие фьючерсы будут выполнены. значения wait вся программа Python не завершится, пока не будут выполнены все ожидающие фьючерсы.

Вы можете избежать явного вызова этого метода, если используете оператор with, который завершит работу Executor (ожидая, как если бы Executor.shutdown () был вызван с параметром wait, установленным в True):

...