等待阻止从队列读取时退出信号

时间:2019-05-17 09:33:44

标签: python multithreading blocking locks

在许多情况下,我有一个工作线程,该工作线程从队列中弹出数据并对其执行操作。在某种情况下,我希望我的工作线程停止。简单的解决方案是在 get 调用中添加 timeout ,并在每次 get 时检查 Event / flag超时。但是,这有两个问题:

  • 导致不必要的上下文切换
  • 延迟关机直到发生超时

是否有更好的方法来监听队列中的停止事件和新数据?是否可以同时收听两个队列并阻塞直到第一个队列中有数据? (在这种情况下,可以使用第二个Queue来触发关闭。)

我当前正在使用的解决方案:

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..")

1 个答案:

答案 0 :(得分:0)

我想您可以轻松地将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..")

另一种选择是使用套接字而不是队列。