Я пытаюсь понять, как работает параметр timeout в пакете concurrent.futures.ProcessPoolExecutor
. Проблема, с которой я сталкиваюсь, заключается в том, что процессы работают дольше, чем указано в параметре timeout в executor.map()
.
Мой код ниже:
import time
import concurrent.futures
def sleeper(duration):
time.sleep(duration)
print("slept for duration ", str(duration))
return duration * -1
def main():
times = [1, 4, 15, 3]
with concurrent.futures.ProcessPoolExecutor(max_workers=6) as executor:
for result in executor.map(sleeper, times, timeout=10):
print(result)
if __name__ == "__main__":
main()
Поскольку время ожидания составляет 10 секунд, я бы исключил функцию для печати
slept for duration 1
-1
slept for duration 3
slept for duration 4
-4
, за которым следует ошибка тайм-аута, поскольку достигается 10 секунд, прежде чем функция будет переведена в спящий режим на 15 секунд Вместо этого я получаю следующее:
slept for duration 1
-1
slept for duration 3
slept for duration 4
-4
slept for duration 15
Traceback (most recent call last):
File "debug_processpoolexecutor.py", line 17, in <module>
main()
File "debug_processpoolexecutor.py", line 13, in main
for result in executor.map(sleeper, times, timeout=10):
File "C:\Users\user\AppData\Local\Continuum\anaconda3\lib\concurrent\futures\process.py", line 476, in _chain_from_iterable_of_lists
for element in iterable:
File "C:\Users\user\AppData\Local\Continuum\anaconda3\lib\concurrent\futures\_base.py", line 588, in result_iterator
yield fs.pop().result(end_time - time.monotonic())
File "C:\Users\user\AppData\Local\Continuum\anaconda3\lib\concurrent\futures\_base.py", line 434, in result
raise TimeoutError()
concurrent.futures._base.TimeoutError
Как видите, функция фактически спит в течение 15 секунд, а затем возвращает ошибку тайм-аута в течение 10 секунд. Это побеждает цель завершения процесса, который застрял (в моем реальном приложении).
Почему функция позволяет завершить работу в течение 15 секунд? Как я могу заставить его вернуть исключение, если оно длится дольше 10 секунд, без необходимости ждать 15 секунд?