这不是一个明确的答案,但是应该涵盖我已经设法收集的有关此问题的相关详细信息。
首先,Python的线程实现基于Java的。Java的Condition.signal()
文档内容如下:
一个实现可能(并且通常确实)要求在调用此方法时当前线程持有与此Condition相关联的锁。
现在,问题是为什么特别在Python中 强制执行 此行为。但是首先,我想介绍每种方法的利弊。
关于为什么有人认为握住锁通常是一个更好的主意,我发现了两个主要论点:
从服务员一刻开始acquire()
(即在释放它之前),wait()
可以确保收到信号通知。如果相应的release()
发生在信令之前,则这将允许序列(其中 P = Producer 和 C = Consumer ),P: release(); C: acquire(); P: notify(); C: wait()
在这种情况下,wait()
与acquire()
相同流的对应将丢失信号。在某些情况下,这无关紧要(甚至可以认为更准确),但是在某些情况下,这是不希望的。这是一个论点。
当您notify()
不在锁中时,这可能会导致调度优先级倒置。也就是说,低优先级的线程最终可能会优先于高优先级的线程。考虑一个生产队列,其中有一个生产者和两个消费者( LC =低优先级消费者 , HC =高优先级消费者 ),其中 LC 当前正在执行工作项,而 HC 在中阻塞wait()
。
可能会发生以下顺序:
P LC HC
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
execute(item) (in wait())
lock()
wq.push(item)
release()
acquire()
item = wq.pop()
release();
notify()
(wake-up)
while (wq.empty())
wait();
鉴于notify()
以前发生过这种情况release()
, LCacquire()
在 HC 唤醒之前是无法做到的。这是发生优先级反转的地方。这是第二个论点。
支持在锁之外进行通知的论点是针对高性能线程,其中线程不必为了进入下一个时间片而再次唤醒而重新进入睡眠状态,这已经在线程中进行了解释。我的问题。