Python 在退出命令时退出多个线程

Python 在退出命令时退出多个线程,python,python-3.x,multithreading,Python,Python 3.x,Multithreading,我有一个线程,它将在命令行中输入的命令添加到命令队列中。其中一个命令是退出程序的命令 def cli(cmd_queue): while True: i = input() if i == "q": cmd_queue.put(("QUIT",)) return cmd_queue = queue.Queue() cli_thread = threading.Thread(target=cli,

我有一个线程,它将在命令行中输入的命令添加到命令队列中。其中一个命令是退出程序的命令

def cli(cmd_queue):
    while True:
        i = input()  
        if i == "q":
            cmd_queue.put(("QUIT",)) 
            return  

cmd_queue = queue.Queue()

cli_thread = threading.Thread(target=cli, args=(cmd_queue,), daemon=True)
cli_thread.start()
我可以这样结束另一个线程:

def some_thread():
    while True:

       while not cmd_queue.empty():
         cmd = cmd_queue.get()
         if cmd == ("QUIT",): return

         do_stuff()

       time.sleep(0.001)
但是,如果我的程序中有几个线程,并且我希望所有线程都突破
而不是True
循环,我该怎么办呢

更新

我希望突破的线程有不同的算法,例如:

def some_thread_1():
    while True:

       while not cmd_queue.empty():
         cmd = cmd_queue.get()
         if cmd == ("QUIT",): return

         do_stuff()

       time.sleep(0.001)

def some_other_thread_2():
    while True:

       while not cmd_queue.empty():
         cmd = cmd_queue.get()
         if cmd == ("QUIT",): return

         do_other_stuff()

       time.sleep(0.001)

正如注释所建议的,为每个线程设置一个sentinel值,以发出退出信号。这里有一个例子。线程不可能得到两个哨兵,因为一旦得到一个哨兵,它们就停止从队列中抽取

from threading import Thread
from queue import Queue
import time

q = Queue()

# Factory function for creating functions with fixed multipliers of input data.
def mult_factory(n):
    def mult(n=n):
        while True:
            data = q.get()
            if data is None: # Sentinel value?
                break
            print(f'{data} * {n} = {data * n}')
        print(f'Quitting mult{n}')
    return mult

# Create 5 threads with different multiplication factors.
threads = [Thread(target=mult_factory(n)) for n in range(5)]

for t in threads:
    t.start()

# Generate some work
for i in range(10):
    q.put(i)

# Add a "done" for each thread.
for t in threads:
    q.put(None)

for t in threads:
    t.join()
输出:

0 * 1 = 0
1 * 3 = 3
3 * 4 = 12
7 * 4 = 28
8 * 4 = 32
9 * 4 = 36
6 * 3 = 18
5 * 1 = 5
Quitting mult4
Quitting mult3
Quitting mult1
2 * 0 = 0
4 * 2 = 8
Quitting mult0
Quitting mult2

您为每个线程向队列中提供一个QUIT元组。@quamrana因此,如果还有四个线程对命令感兴趣,我会将给定的命令向队列中提供四次。这个解决方案不存在这样的风险:一个线程会看到该命令两次,而另一个线程会完全错过同一个命令。有四个命令队列,每个线程一个怎么样?@Baz不,因为当一个线程收到退出消息时,它退出,不再从队列中提取任何请求:)谢谢你的回复!在上述情况下,您的解决方案非常有意义。我刚刚开始开发我的应用程序,所以我不知道这对我来说是否会是个问题,但我在想,如果我在代码的其他地方创建了更多不相关的线程,比如使用除法工厂和减法工厂创建的话,会怎么样。在这种情况下,我需要知道代码中的线程数,才能将正确的退出次数添加到命令队列中。除了“退出”之外,我可能还想向那些感兴趣的线程广播其他命令。@Baz为正在创建的线程使用一个公共列表,这样您就知道您总共有多少个线程了。此外,队列项目可以是任何类型,因此您可以使用一个特殊的类而不是
None
来保存命令和工作,并使用
对它们进行测试,如果isinstance(数据,命令):
则查询对象以获取命令。在这种简单的情况下,您可以使用
int
进行工作,使用
str
执行命令。@Baz此外,对于线程池使用的公共队列,只有“quit”类型的命令才能工作。对于其他命令,每个线程都需要有目标的命令队列,因为否则同一线程可能会拾取一个命令两次。