在许多情况下,我有一个工作线程,该线程从队列中弹出数据并在其上作用。在某种情况下,我希望我的工作线程停止。简单的解决方案是将超时添加到 get 调用,并每次 get get 检查 emb> event /flag时代。但是,这是两个问题:
- 导致不必要的上下文开关
- 延迟关闭直到超时发生
是否有更好的方法来聆听停止事件和队列中的新数据?是否可以同时收听两个队列并阻止第一个队列?(在这种情况下,可以使用第二个队列来触发关闭。(
我目前正在使用的解决方案:
from queue import Queue, Empty
from threading import Event, Thread
from time import sleep
def worker(exit_event, queue):
print("Worker started.")
while not exit_event.isSet():
try:
data = queue.get(timeout=10)
print("got {}".format(data))
except Empty:
pass
print("Worker quit.")
if __name__ == "__main__":
exit_event = Event()
queue = Queue()
th = Thread(target=worker, args=(exit_event, queue))
th.start()
queue.put("Testing")
queue.put("Hello!")
sleep(2)
print("Asking worker to quit")
exit_event.set()
th.join()
print("All done..")
我想您可以很容易地将timeout
降低至0.1 ... 0.01秒。略有不同的解决方案是使用队列将数据和控制命令同时发送到线程:
import queue
import threading
import time
THREADSTOP = 0
class ThreadControl:
def __init__(self, command):
self.command = command
def worker(q):
print("Worker started.")
while True:
data = q.get()
if isinstance(data, ThreadControl):
if data.command == THREADSTOP:
break
print("got {}".format(data))
print("Worker quit.")
if __name__ == '__main__':
q = queue.Queue()
th = threading.Thread(target=worker, args=(q,))
th.start()
q.put("Testing")
q.put("Hello!")
time.sleep(2)
print("Asking worker to quit")
q.put(ThreadControl(command=THREADSTOP)) # sending command
th.join()
print("All done..")
另一个选择是使用套接字而不是队列。