gpt4 book ai didi

python - Python线程未释放锁

转载 作者:行者123 更新时间:2023-12-03 13:02:00 25 4
gpt4 key购买 nike

在使用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()
问题是,线程在释放锁定之后要做的下一件事是,它再次获取它。
想象一下,您在门锁着的浴室里。有人在外面等着进去。您已经让他们等了很长一段时间,所以也许他们坐下来了。突然,您打开门,走了出去,而在另一个人还没有时间站起来之前,您又走回室内并再次锁上了门。
这大致就是您的程序中正在发生的事情。
锁对一件事有好处,并且仅对一件事有好处:您可以使用它们来阻止两个线程同时使用相同的资源。如果您尝试将它们用于其他任何目的(例如,控制线程执行操作的顺序),那么您将很难。

在许多编程语言/库中,一个线程发信号通知另一个线程的最原始方法称为条件变量。参见 https://docs.python.org/3/library/threading.html#condition-objects

关于python - Python线程未释放锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65905098/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com