【问题标题】:How to stop daemon thread?如何停止守护线程?
【发布时间】:2016-12-13 21:47:48
【问题描述】:

我有一个简单的生产者消费者应用程序。

生产者是一个将内容写入队列的线程,而消费者是一个从队列中读取消息并在某些时候退出的线程。

我的制作人有点像这个

def producer(queue):
    while not queue.full():
        queue.put(randint(1, 199))

和消费者

def consumer(queue):
    for i in range(100):
        print(queue.get())
        queue.task_done()

在我的 main 中,我像这样调用那些线程

p = Thread(target=producer)
c = Thread(target=consumer)

p.daemon = True
p.start()
c.start()
c.join()

c 完成唯一剩下的非守护线程是主线程时,结束这些线程的正确方法是什么?

更新

这是我的生产者正在使用的确切代码,因为消费者正在退出并且问题在于生产者

def generate_random_alphanumerics(msg_queue):
    while True:
        if not msg_queue.full():
            msg_queue.put(hashlib.sha1(bytes(randint(1, 10000))).hexdigest() * 10)
        else:
            sleep(0.01)

是线程休眠的问题吗?

【问题讨论】:

  • 您不必停止守护线程。当主线程结束时,它们将自动终止。更详细的解释见我的this answer
  • 但程序仍然挂起而不是退出
  • 即使我添加了不需要的sys.exit()
  • @LetsPlayYahtzee:我怀疑您当时忽略了代码的关键部分。如果你在start之前正确地将线程设置为daemon,它应该不需要特殊的扭曲来退出。
  • LetsPlayYahtzee:不,您不需要明确调用sys.execit()。您问题中的示例代码不能准确表示您的真实代码。看完How to create a Minimal, Complete, and Verifiable example后请edit

标签: python multithreading python-3.x python-multithreading


【解决方案1】:

问题是生产者循环永远不会结束,所以你应该有办法让它停止。

stop_event= threading.Event()
p = Thread(target=producer, args=(msg_queue, stop_event))
p.start()

生产者变成:

def generate_random_alphanumerics(msg_queue, stop_event):
    while not stop_event.is_set():
        if not msg_queue.full():
            [...]

然后,当您想停止生产者时,只需执行以下操作:

stop_event.set()

【讨论】:

  • 很好的答案,我一定是瞎了眼,否则在任何地方都没有这么简单的提及