У меня N рабочих потоков, все они читают из одного queue.SimpleQueue
, где основная программа записывает задачи для выполнения.Когда поток получает сообщение из очереди, его задача может длиться несколько минут.Таким образом, если основная программа прерывается (например, CTRL-C или SIGINT), может пройти много времени, прежде чем все потоки завершатся.Однако я бы хотел, чтобы программа завершилась через несколько секунд.Задача, которую поток выполняет , может быть прервана, однако, , что означает, что поток может периодически проверять флаг или переменную события, чтобы определить, должен ли он завершиться.
Так что я придумалСледующее сочетание сторожевых сообщений и переменных событий для достижения цели:
import queue
import threading
# worker thread
def worker_loop(work_queue, thread_id, event):
while True:
end = False
item = work_queue.get()
# work_queue.task_done() # not needed for SImpleQueue
if item is None:
print("Thread %s: terminating due to sentinel" % thread_id)
end = True
else:
# perform task, periodically checking for event
for part in range(10):
print("Thread %s: doing job part %s (item %s)" % (thread_id, part, item))
do_work(part = part) # this lasts a few seconds
result = event.wait(timeout = 0.01)
if result == True:
print("Thread %s: terminating due to event" % thread_id)
end = True
break
if end:
return
# main
WORKERS = 5
THREADS = []
work_queue = queue.SimpleQueue()
event = threading.Event()
for thread_id in range(WORKERS):
print("[Main] creating thread '%s'" % thread_id)
t = threading.Thread(target = worker_loop, args = (work_queue, thread_id, event))
THREADS.append(t)
t.start()
# main code here...
# ...
# we received a signal, the time has come to terminate all threads...
# kill threads waiting on the queue
for i in range(NUM_THREADS):
work_queue.put(None)
# signal other threads to terminate ASAP
event.set()
# wait for all threads to terminate
for thread_id in range(NUM_THREADS):
THREADS[thread_id].join()
sys.exit()
Мой вопрос: безопасен ли этот метод?Мне кажется, что это так, но я решил, что лучше проверить.Есть ли лучшие / более элегантные альтернативы?