首页 > 解决方案 > 使用键盘中断停止所有在队列上工作的线程

问题描述

我有以下代码:

from Queue import Queue
from threading import Thread

num_worker_threads = 10

# some items to work on
def source():
    return xrange(400)

# the actual work to be done
def do_work(smth):
    # some really heavy task here
    print("{}\r".format(smth))

# worker that retrieves data from queue and executes work
def worker():
    while True:
        item = q.get()
        do_work(item)
        q.task_done()

q = Queue()
for i in range(num_worker_threads):
     t = Thread(target=worker)  #use args to pass args
     t.daemon = True
     t.start()

# queues items to work on
for item in source():
    q.put(item)

# blocks until work is finished
q.join()  

按 Ctrl+C 时如何停止所有线程?当我这样做时,程序执行将继续。

我在 StackOverflow 上看到过类似的问题,但他们不使用join().

我对我应该在这里包装什么以及我应该try..except如何停止线程感到困惑?

标签: pythonmultithreadingpython-multithreading

解决方案


通过调用q.join(),您只是在等待线程结束。您需要能够告诉线程(从主线程)停止其执行。

一个很好的方法是改变你的工人的实现。它不应该是一个函数,而应该是一个继承自 threading.Thread 的类。

您可以提供Worker一个可以从告诉它停止工作的主线程更改的属性。

import threading
class Worker(threading.Thread):
    def __init__(self, queue):
        self.keep_doing_work = True
        self.q = queue
        threading.Thread.__init__(self)

    def run(self):
        while self.keep_doing_work is True:
            item = self.q.get()
            self.do_work(item)
            q.task_done()

    def do_work(smth):
        print("{}\r".format(smth))

num_worker_threads = 10

my_threads = []

try:
    for i in range(num_worker_threads):
        t = Worker()
        my_threads.append(t)
        t.start()

except KeyboardInterrupt:
    for t in my_threads:
        t.keep_doing_work = False   


推荐阅读