而python中的循环不';当它包含锁时,t结束
我目前正在学习在Python中使用线程,我正在练习以下虚拟代码:而python中的循环不';当它包含锁时,t结束,python,multithreading,queue,locking,Python,Multithreading,Queue,Locking,我目前正在学习在Python中使用线程,我正在练习以下虚拟代码: import threading import queue import time my_queue = queue.Queue() lock = threading.Lock() for i in range(5): my_queue.put(i) def something_useful(CPU_number): while not my_queue.empty(): lock.a
import threading
import queue
import time
my_queue = queue.Queue()
lock = threading.Lock()
for i in range(5):
my_queue.put(i)
def something_useful(CPU_number):
while not my_queue.empty():
lock.acquire()
print("\n CPU_C " + str(CPU_number) + ": " + str(my_queue.get()))
lock.release()
print("\n CPU_C " + str(CPU_number) + ": the next line is the return")
return
number_of_threads = 8
practice_threads = []
for i in range(number_of_threads):
thread = threading.Thread(target=something_useful, args=(i, ))
practice_threads.append(thread)
thread.start()
所有这一切只需创建一个包含5个项目的队列,然后将它们拉出,并使用不同的线程打印它们
不过,我注意到一些线程没有正确终止。例如,如果我后来在队列中添加了一些内容(例如,my_queue.put(7)
),那么一些线程将立即打印该数字
这就是为什么我添加了最后一个打印行print(“\n CPU\U C”+str(CPU\U编号)+”:下一行是return”)
,我注意到只有一个线程将终止。换句话说,当我运行上面的代码时,只有一个线程会打印“下一行是返回”
奇怪的是,当我打开锁时,这个问题就消失了。没有锁,它工作得非常好
我遗漏了什么?实际上,不只是一个线程会给出
下一行是返回值。可以是1到8之间的任意位置
在我的处决中,有时我得到1,3,4,5,6,7或1,2,3,4,5,6,7或1,4,5,6,7或只有5,6,7等
你有比赛条件
竞赛条件介于while
checknot my_queue.empty()
和lock.acquire()之间
本质上,.empty()
可以给你一个“它不是空的”,但是在你获得锁之前,其他的东西可能会把这个值取出来。因此,您需要检查锁内的这些东西
下面是一个更安全的实现:
import threading
import queue
import time
my_queue = queue.Queue()
lock = threading.Lock()
for i in range(50):
my_queue.put(i)
def something_useful(CPU_number):
while True:
lock.acquire()
if not my_queue.empty():
print("CPU_C " + str(CPU_number) + ": " + str(my_queue.get()))
lock.release()
else:
lock.release()
break
print("CPU_C " + str(CPU_number) + ": the next line is the return")
return
number_of_threads = 8
practice_threads = []
for i in range(number_of_threads):
thread = threading.Thread(target=something_useful, args=(i, ))
practice_threads.append(thread)
thread.start()
注意:在您当前的代码中,因为您只获得了值-它始终是一个拦截器,即整个循环一次只有一个线程。理想情况下,您会:
if not my_queue.empty():
val = my_queue.get()
lock.release()
print("CPU_C " + str(CPU_number) + ": " + str(val))
heavy_processing(val) # While this is going on another thread can read the next val
实际上,不只是一个线程会给出,下一行是返回值。可以是1到8之间的任意位置
在我的处决中,有时我得到1,3,4,5,6,7或1,2,3,4,5,6,7或1,4,5,6,7或只有5,6,7等
你有比赛条件
竞赛条件介于while
checknot my_queue.empty()
和lock.acquire()之间
本质上,.empty()
可以给你一个“它不是空的”,但是在你获得锁之前,其他的东西可能会把这个值取出来。因此,您需要检查锁内的这些东西
下面是一个更安全的实现:
import threading
import queue
import time
my_queue = queue.Queue()
lock = threading.Lock()
for i in range(50):
my_queue.put(i)
def something_useful(CPU_number):
while True:
lock.acquire()
if not my_queue.empty():
print("CPU_C " + str(CPU_number) + ": " + str(my_queue.get()))
lock.release()
else:
lock.release()
break
print("CPU_C " + str(CPU_number) + ": the next line is the return")
return
number_of_threads = 8
practice_threads = []
for i in range(number_of_threads):
thread = threading.Thread(target=something_useful, args=(i, ))
practice_threads.append(thread)
thread.start()
注意:在您当前的代码中,因为您只获得了值-它始终是一个拦截器,即整个循环一次只有一个线程。理想情况下,您会:
if not my_queue.empty():
val = my_queue.get()
lock.release()
print("CPU_C " + str(CPU_number) + ": " + str(val))
heavy_processing(val) # While this is going on another thread can read the next val
谢谢,我没意识到这一点。知道如何修复它吗?比如说:“一旦一个线程获得了锁,后续获取它的尝试就会被阻止,直到它被释放;任何线程都可能释放它。”谢谢,我没有意识到这一点。你知道如何修复它吗?比如说:“一旦一个线程获得了锁,后续获取它的尝试就会阻塞,直到它被释放;任何线程都可以释放它。”一般来说,使用锁访问队列在某种程度上违背了队列
的目的。您也可以在代码中使用列表或collections.deque
而不是queue.queue
。请参见一个不带锁的示例。如何结束线程(队列.Empty:
)取决于您的问题。常见的替代方法是一些停止标志(您可以检查它,而不是简单地返回)或在队列上放置一些“停止”项以停止线程(这样您就不再需要get
超时)。一般来说,使用锁访问队列会有点违背队列的目的。您也可以在代码中使用列表或collections.deque
而不是queue.queue
。请参见一个不带锁的示例。如何结束线程(队列.Empty:
)取决于您的问题。常用的替代方法是一些停止标志(您可以检查它,而不是简单地返回),或者在队列上放置一些“停止”项来停止线程(这样您就不再需要get
的超时)。