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”类型的命令才能工作。对于其他命令,每个线程都需要有目标的命令队列,因为否则同一线程可能会拾取一个命令两次。