Как вы убиваете фьючерсы, когда они начались?
Я использую новыйconcurrent.futures
модуль (который также имеет бэкпорт Python 2) для выполнения простого многопоточного ввода / вывода. У меня возникли проблемы с пониманием, как правильно убить задачи, запущенные с помощью этого модуля
Посмотрите на следующий скрипт Python 2/3, который воспроизводит поведение, которое я вижу:
#!/usr/bin/env python
from __future__ import print_function
import concurrent.futures
import time
def control_c_this():
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
future1 = executor.submit(wait_a_bit, name="Jack")
future2 = executor.submit(wait_a_bit, name="Jill")
for future in concurrent.futures.as_completed([future1, future2]):
future.result()
print("All done!")
def wait_a_bit(name):
print("{n} is waiting...".format(n=name))
time.sleep(100)
if __name__ == "__main__":
control_c_this()
Пока этот скрипт работает, кажется, что невозможно убить чисто, используя обычное прерывание клавиатуры Control-C. Я работаю на OS X.
На Python 2.7 мне приходится прибегать кkill
из командной строки убить скрипт. Control-C просто игнорируется.На Python 3.4 Control-C работает, если вы дважды нажмете на него, но затем сбрасывается много странных следов стека.Большая часть документации, которую я нашел в Интернете, рассказывает о том, как убить потоки со старымthreading
модуль. Ничто из этого, кажется, не применимо здесь.
И все методы, предусмотренные вconcurrent.futures
модуль для остановки вещей (например,Executor.shutdown()
а такжеFuture.cancel()
) работают только тогда, когда Фьючерсы еще не начаты или не завершены, что в данном случае не имеет смысла. Я хочу немедленно прервать будущее.
Мой пример использования прост: когда пользователь нажимает Control-C, скрипт должен завершиться немедленно, как и любой скрипт с хорошим поведением. Это все, что я хочу.
Итак, как правильно получить такое поведение при использованииconcurrent.futures
?