Одной из задач, с которой встречаются разработчики многопоточных/многопроцессных приложений,
является их корректная остановка. Особенно это касается таких потоков/процессов, в которых
осуществляется бесконечная блокирующая операция, типа цикла "while True" или чтения из некоего
генератора.
while True:
# do something
С потоками проще, потому что им можно передать ссылку на объект, который можно проверять
при каждой итерации и останавливать при соблюдении условий.
import time
from threading import Thread
def in_thread(con):
while con[0]:
# ... doing something
pass
con = [True]
t = Thread(target=in_thread, args=(con,))
t.start()
time.sleep(3)
# Stop the thread
con[0] = False
t.join()
С процессами несколько иначе, они более изолированные, и нужно использовать объекты синхронизации.
Очень удобный способ мне подсказал коллега, с использованием Lock.
import time
from threading import Thread
from multiprocessing import Process, Lock
def in_process(lock):
def in_thread(con):
while con[0]:
pass
# ... doing something
con = [True]
t = Thread(target=in_thread, args=(con,))
t.daemon = True
t.start()
# Lock acquired in parent process, child process waits, but thread already ran!
lock.acquire()
# Polite way
con[0] = False
t.join()
# Way for impatient
# import os
# os._exit(0)
lock = Lock()
lock.acquire()
Process(target=in_process, args=(lock,)).start()
time.sleep(3)
# ... process in action ...
# Release lock, child process going to be finished
lock.release()