Одна из проблем с многопоточностью в python заключается в том, что join()
более или менее отключает сигналы.
Это связано с тем, что сигнал может быть доставлен только в основной поток, но основной поток уже занят выполнением join()
и соединение не может быть прервано.
Вы можете сделать вывод из документации модуля signal
Следует проявлять некоторую осторожность, если в одной и той же программе используются и сигналы, и потоки. Фундаментальная вещь, которую следует помнить при одновременном использовании сигналов и потоков: всегда выполняйте операции signal() в основном потоке выполнения. Любой поток может выполнять функции alarm(), getsignal(), pause(), setitimer() или gettimer(); только основной поток может установить новый обработчик сигналов, и основной поток будет единственным, кто будет получать сигналы (это обеспечивается сигнальным модулем Python, даже если базовая реализация потока поддерживает отправку сигналов в отдельные нити). Это означает, что сигналы нельзя использовать в качестве средства межпоточной связи. Вместо этого используйте замки.
Вы можете обойти это, зациклив операцию соединения:
for t in threads:
while t.isAlive():
t.join(timeout=1)
Это, однако, неэффективно:
Обходной путь вызова join() с тайм-аутом имеет недостаток: процедура ожидания многопоточности Python опрашивает 20 раз в секунду при любом тайм-ауте. Весь этот опрос может означать множество прерываний/пробуждения процессора на бездействующем ноутбуке и быстрее разряжать аккумулятор.
Некоторые подробности приведены здесь:
Программа Python с потоком не может поймать CTRL+C
Отчеты об ошибках для этой проблемы с обсуждением основной проблемы можно найти здесь:
https://bugs.python.org/issue1167930
https://bugs.python.org/issue1171023
person
dhke
schedule
15.04.2015