Sea*_*ene 5 python queue multithreading
测试代码非常简单:
import threading, Queue
import time, random
class Worker(threading.Thread):
def __init__(self, index, queue):
threading.Thread.__init__(self)
self.index = index
self.queue = queue
def run(self):
while 1:
time.sleep(random.random())
item = self.queue.get()
if item is None:
break
print "index:", self.index, "task", item, "finished"
self.queue.task_done()
queue = Queue.Queue(0)
for i in range(2):
Worker(i, queue).start()
for i in range(10):
queue.put(i)
for i in range(2):
queue.put(None)
print "Main OK"
Run Code Online (Sandbox Code Playgroud)
每次运行时结果都会有所不同,这里只有一个:
Main OK
index: 1 task 0 finished
index: 0 task 1 finished
index: 0 task 2 finished
index: 1 task 3 finished
index: 1 task 4 finished
index: 0 task 5 finished
index: 1 task 6 finished
index: 0 task 7 finished
index: 1 task 8 finished
index: 1 task 9 finished
Run Code Online (Sandbox Code Playgroud)
IMO当主线程终止时,将打印"Main OK",然后第一个线程将被执行直到它进入time.sleep(random.random()),然后第一个线程将休眠,第二个线程将继续.与第一个线程相同,第二个线程在进入时会睡眠time.sleep(random.random()),然后第一个线程将再次继续.并且它会index:0 task 0 finished在之后打印Main OK,但实际上接下来Main OK的index: 1...不是index: 0...!为什么?似乎队列不像普通的多线程那样运行,有时同一个索引线程会连续执行三次或更多次!Queue机制在什么地方工作?任何帮助赞赏!
你有三个线程;两个工作线程和一个主线程。这三者几乎同时运行。您的建议(您事先会知道的明确切换)并不正确。您在队列填满之前启动工作线程,因此它们立即开始进入 sleep() 状态。然后你填满队列。很可能其中一个线程会在另一个线程之前离开 sleep() 并从队列中获取第一个项目,将处理它(打印)并再次进入下一个 sleep() 。有可能(由于随机)第一个 Worker 每次都会休眠 0.01 秒,而另一个从一开始就休眠 0.4 秒,然后所有项目都将由第一个进程处理。
如果多个 Worker 线程在 Queue.get() 方法中阻塞(只有在队列尚未填满时都离开 sleep() 时才会发生),您无法确定唤醒哪个 Worker 线程来处理该项目。
您的随机睡眠同步程度不够,无法在两个工作人员之间进行清晰的来回切换,因为一个工作人员可能会在随机睡眠中睡得太久,以致另一个线程同时处理两个项目。始终尝试在两个进程之间进行清晰的切换:
def run(self):
if self.index == 0:
time.sleep(0.1)
while 1:
time.sleep(0.2)
item = self.queue.get()
if item is None:
break
print "index:", self.index, "task", item, "finished"
self.queue.task_done()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4191 次 |
| 最近记录: |