【发布时间】:2018-02-15 00:02:36
【问题描述】:
由于不必要的性能影响,我的问题特别提到了为什么要这样设计。
当线程 T1 有这个代码时:
cv.acquire()
cv.wait()
cv.release()
线程 T2 有这个代码:
cv.acquire()
cv.notify() # requires that lock be held
cv.release()
发生的情况是 T1 等待并释放锁,然后 T2 获取它,通知 cv 唤醒 T1。现在,T2 的发布和 T1 从wait() 返回后重新获取之间存在竞争条件。如果 T1 先尝试重新获取,它将不必要地重新挂起,直到 T2 的 release() 完成。
注意:我故意不使用with 语句,以便通过显式调用更好地说明比赛。
这似乎是一个设计缺陷。是否有任何已知的理由,或者我错过了什么?
【问题讨论】:
-
pthread_cond_signal(3)可能会提供信息 -
@o11c 确实,谢谢,问题是:
The pthread_cond_broadcast() or pthread_cond_signal() functions may be called by a thread whether or not it currently owns the mutex that threads calling pthread_cond_wait() or pthread_cond_timedwait() have associated with the condition variable during their waits -
那么 python 又被过度限制了。诚然,您通常希望即使在 C 中也能持有锁。
-
通过快速查看其他语言的同步原语,这个要求在Java和C#中也存在,但在pthreads、Windows条件变量或c++11条件变量中不存在。您通常希望为
notify与其他线程相关的任何内容持有锁,但为notify本身持有锁的要求似乎没有必要。它可能是从需要锁来保护条件变量本身的历史设计中复制而来的,或者它可能被认为促进更安全的锁使用。 -
如果您不必考虑其他线程在您通知的内容和实际的通知调用之间进行调解,那么推理正确性肯定会更容易。特别是对于像 Python 这样的语言,仅出于这个原因,我就会支持这个设计决策。我怀疑实际的历史原因是他们复制了 Java 所做的事情。文档确实提到
threading模块是基于 Java 的设计。
标签: python multithreading python-3.x race-condition condition-variable