Python中多线程时queue.queue的正确实现
我正在学习python,并编写了一些简单的脚本,为自己提供各种主题的实际示例。其中一个脚本演示了如何将queue.queue()与threading.Thread()一起使用来创建后台工作人员。不过,它的行为相当奇怪。我做了一些计时赛。只需一个线程,它就会像您所期望的那样。。。每项任务大约需要2秒(实际上不到40秒)才能完成这20项任务。有了四个线程,它会像您所期望的那样再次运行。它一次完成4项任务,因此大约需要10秒。那么,当我运行20个线程时,地球是如何运行的呢?它需要0.01秒(1s.f.)——肯定需要2秒吗 代码如下:Python中多线程时queue.queue的正确实现,python,multithreading,Python,Multithreading,我正在学习python,并编写了一些简单的脚本,为自己提供各种主题的实际示例。其中一个脚本演示了如何将queue.queue()与threading.Thread()一起使用来创建后台工作人员。不过,它的行为相当奇怪。我做了一些计时赛。只需一个线程,它就会像您所期望的那样。。。每项任务大约需要2秒(实际上不到40秒)才能完成这20项任务。有了四个线程,它会像您所期望的那样再次运行。它一次完成4项任务,因此大约需要10秒。那么,当我运行20个线程时,地球是如何运行的呢?它需要0.01秒(1s.f.
import threading
from queue import Queue
import time
q = Queue()
tLock = threading.Lock()
def run() :
while True :
task = q.get()
print('Just finished task number',task)
q.task_done()
time.sleep(2)
def main() :
# worker threads are activated
for x in range(20) :
t = threading.Thread(target=run)
t.daemon = True
t.start()
#20 jobs are put in the queue
for x in range(1,21) :
q.put(x)
#waits until queue is empty and then continues
q.join()
if __name__ == '__main__' :
startTime = time.time()
main()
print('Time taken was', time.time() - startTime)
实际上,您并没有阻止主线程的进程: “正确的”(*)方法是通过连接所有线程来确保完成所有线程:
def main() :
# keep reference to threads
threads = [threading.Thread(target=run) for _ in range(20)]
# start all threads
for t in threads:
t.start()
#20 jobs are put in the queue
for x in range(1,21) :
q.put(x)
#waits until queue is empty and then continues
q.join()
# join all threads
for t in threads:
t.join()
*但是,这将不起作用,因为线程处于无限循环中,即使任务已经完成
因此,另一种方法是确保在报告任务之前等待:
def run() :
while True :
task = q.get()
# simulate processing time *before* actual reporting
time.sleep(2)
print('Just finished task number',task)
q.task_done()
不过,线程仍然被阻塞。你可以选择给线程一条消息,告诉他们退出。比如:
def run() :
while True :
task = q.get()
if task == 'stop':
break
# simulate processing time *before* actual reporting
time.sleep(2)
print('Just finished task number',task)
q.task_done()
现在只需告诉主线程放置足够的停止消息,以便所有线程最终退出其无限循环:
def main() :
# keep reference to threads
threads = [threading.Thread(target=run) for _ in range(20)]
# start all threads
for t in threads:
t.start()
#20 jobs are put in the queue
for x in range(1,21):
q.put(x)
for x in range(20):
# stop all threads after tasks are done
q.put('stop')
# waits until queue is empty and then continues
q.join()
# join all threads
for t in threads:
t.join()
提示:你不应该使用“幻数”,如
20
。在模块级有一个名为THREADS\u COUNT
的全局变量,因此,当您想测试不同的配置时,只需更改一个位置。这是一个很好的答案,我一直将此作为我在该主题上的主要参考,因此编辑了标题,使其他人更容易看到它。谢谢,如果你有任何改进的建议,欢迎。