Jas*_*siu 6 python locking producer-consumer thread-safety
我最近编写了一个使用简单生产者/消费者模式的程序.它最初有一个与不正确使用线程有关的错误.我最终解决了这个问题.但它让我想到是否有可能以无锁的方式实现生产者/消费者模式.
我的要求很简单:
所以我写了这个:
QUEUE_ITEM = None
# this is executed in one threading.Thread object
def producer():
global QUEUE_ITEM
while True:
i = produce_item()
QUEUE_ITEM = i
# this is executed in another threading.Thread object
def consumer():
global QUEUE_ITEM
while True:
i = QUEUE_ITEM
consume_item(i)
Run Code Online (Sandbox Code Playgroud)
我的问题是:这段代码是否是线程安全的?
直接评论:这段代码不是真的无锁 - 我使用CPython并且它有GIL.
我测试了一点代码,它似乎工作.它转换为一些由于GIL而成为原子的LOAD和STORE操作.但是我也知道del x当x实现__del__方法时,操作不是原子的.因此,如果我的项目有__del__方法并且发生了一些讨厌的调度,那么事情可能会破裂.或不?
另一个问题是:为了使上述代码正常工作,我必须施加什么样的限制(例如生成的项目类型)?
我的问题只是关于利用CPython和GIL的怪癖的理论可能性,以便提出无锁(即没有像代码中的threadading.Lock那样的锁)解决方案.
是的,这将以您描述的方式工作:
但我也知道,当 x 实现del方法时,del x 操作不是原子的。因此,如果我的项目有del方法并且发生了一些令人讨厌的调度,事情可能会崩溃。
我在这里没有看到“del”。如果del发生在consume_item中,那么del可能发生在生产者线程中。我不认为这会是一个“问题”。
不过不用费心使用这个。你最终会在毫无意义的轮询周期上耗尽 CPU,而且它并不比使用带锁的队列快,因为 Python 已经有了全局锁。