作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在使用Python中的锁创建简单的使用者生产者线程结构时,我遇到了一些问题,这些问题导致程序创建了意外的输出。
import threading
from time import sleep
import random
class AI:
def __init__(self):
self.a = None
self.mainLock = threading.Lock()
threading.Thread(target=self.producer,daemon=True).start()
threading.Thread(target=self.consumer,daemon=True).start()
def producer(self):
while True:
self.mainLock.acquire()
sleep(1)
temp = random.randint(-1,10)
print(f"Produced {temp}")
self.a = temp
self.mainLock.release()
def consumer(self):
while True:
self.mainLock.acquire()
if(self.a and self.a>0):
sleep(1.5)
print(f"Consumed {self.a}")
self.a = None
self.mainLock.release()
a = AI()
input()
输出 -
Produced 0
Produced 8
Produced 9
Produced 1
Produced 9
Produced 10
Produced 5
Produced 1
这显然不是这里预期的。预期的产出本来会限制生产者之后的消费者。但是,如果在释放生产者内部的锁之后添加任何语句,则代码可以正常运行。
import threading
from time import sleep
import random
class AI:
def __init__(self):
self.a = None
self.mainLock = threading.Lock()
threading.Thread(target=self.producer,daemon=True).start()
threading.Thread(target=self.consumer,daemon=True).start()
def producer(self):
while True:
self.mainLock.acquire()
sleep(1)
temp = random.randint(-1,10)
print(f"Produced {temp}")
self.a = temp
self.mainLock.release()
## = Newly added line
########################
print("released")
########################
def consumer(self):
while True:
self.mainLock.acquire()
if(self.a and self.a>0):
sleep(1.5)
print(f"Consumed {self.a}")
self.a = None
self.mainLock.release()
a = AI()
input()
输出 -
Produced 10
released
Consumed 10
Produced 7
released
Consumed 7
Produced 2
released
Consumed 2
即使将print语句替换为sleep语句,该代码也可以工作,无论休眠持续时间有多短,仍然可以正常工作。
sleep(0.0000000000000000000000000000000000000000000000000000000000000000000000001)
为什么会这样呢?在消费者发布之后,代码如何能够在没有任何打印或 sleep 的情况下从消费者跳回生产者,而没有这些代码,则无法从消费者跳到生产者?
最佳答案
释放锁并不能自动确保其他等待线程会立即获取该锁。
特别是,这是一种反模式:
while (True):
someLock.acquire()
...
someLock.relase()
问题是,线程在释放锁定之后要做的下一件事是,它再次获取它。
关于python - Python线程未释放锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65905098/
我是一名优秀的程序员,十分优秀!