condition.acquire(threading.Condition())是否类似于lock.acquire(threading.Lock)。两者都可以访问该锁。我可以使用condition.wait,通过lock.acquire进行通知,还是必须使用condition.wait,以condition.acquire进行通知。
cond.acquire() // can i replace with lock.acquire
while count[ipID]> 1:
cond.wait()
if ipID == 0:
time.sleep(10)
count[ipID] = count[ipID] + 1
cond.release() // can i replace with lock.release
最佳答案
如果您的条件是这样创建的:
lock = Lock()
cond = Condition(lock)
…然后是的,正如the docs解释的那样,
cond.acquire()
只是调用lock.acquire()
,因此您可以这样做,并获得相同的效果。对于release
同样如此。但是,这可能会误导人类读者(也许还会误导静态分析工具),因此,除非您有充分的理由,否则不应该这样做。另一方面,如果它们是不相关的对象,则按以下方式创建:
lock = Lock()
cond = Condition()
… 那就不要。如果您尚未获得条件使用的锁,则调用
cond.wait()
是非法的。保证会引发一个RuntimeError
。是否有其他Lock
对象碰巧确保其他人不会访问cond
则无关紧要; cond.wait
的全部要点是它原子地释放了自己的锁并阻塞了notify
,因此,如果未持有其锁,则它作为条件是无用的。附带说明一下,同时获取
Lock
和Condition
in a with
statement几乎总是更好的:with cond:
with count[ipID] > 1:
cond.wait()
if ipID == 0:
time.sleep(10)
count[ipID] = count[ipID] + 1
您编写事情的方式(如果
acquire
之后的任何内容引发异常),您将永远不会释放条件,因此没有其他等待它的线程可以唤醒。当我们使用它时,使用
sleep
几乎总是表明您的线程设计有问题。为什么不能只用wait(timeout=10)
代替呢?如果您有太多虚假的notify
调用,则应解决此问题。如果count[ipID]
未正确重置,则while
循环可能会提前退出,因此修复起来尤为重要。无论您认为使用sleep
解决了什么问题,都可能只是在掩饰它。