Завершите программу Python мультипотока

Я не поместил бы константу на параметры как этот - все уже знают что булевская переменная (в противоположность boolean&) является постоянным, так включает, это заставит людей думать, "ожидают, что?" или даже что Вы передаете параметр ссылкой.

71
задан jack 29 October 2009 в 07:09
поделиться

2 ответа

Сделать каждый поток, кроме главного, демоном ( t.daemon = True в версии 2.6 или выше, t.setDaemon (True) в версии 2.6 или меньше, для каждого объекта потока t перед его запуском). Таким образом, когда основной поток получает KeyboardInterrupt, если он не улавливает его или не улавливает, но все равно решил завершить, весь процесс завершится. См. документы .

редактировать : только что увидев код OP (изначально не опубликованный) и утверждение, что «это не работает», похоже, я должен добавить ... :

Конечно, если вы хотите, чтобы ваш основной поток оставался отзывчивым (например, для Control-C), не забивайте его в блокирующие вызовы, такие как join в другом потоке - особенно не полностью бесполезные блокирующие вызовы, например, join ing демон потоков. Например, просто измените последний цикл в основном потоке с текущего (безупречный и опасный):

for i in range(0, thread_count):
    threads[i].join()

на что-то более разумное, например:

while threading.active_count() > 0:
    time.sleep(0.1)

, если вашему основному потоку нечего делать лучше, чем для завершения всех потоков на своем собственные, или для получения Control-C (или другого сигнала).

Конечно, есть много других шаблонов, которые можно использовать, если вы предпочитаете, чтобы ваши потоки не завершались внезапно (как это могут делать демонические потоки) - если только они тоже навсегда погрязли в безоговорочно блокирующих вызовах, тупиках и т.п.; -).

91
ответ дан 24 November 2019 в 13:03
поделиться

Есть два основных способа, один чистый и один простой.

Чистый способ - поймать KeyboardInterrupt в вашем основном потоке и установить флаг, который фоновые потоки могут проверить, чтобы они знали выйти; вот простая / слегка запутанная версия с использованием глобального:

exitapp = False
if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        exitapp = True
        raise

def threadCode(...):
    while not exitapp:
        # do work here, watch for exitapp to be True

Беспорядочный, но простой способ - поймать KeyboardInterrupt и вызвать os._exit (), который немедленно завершает все потоки.

16
ответ дан 24 November 2019 в 13:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: