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,因此,如果未持有其锁,则它作为条件是无用的。

附带说明一下,同时获取LockCondition 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解决了什么问题,都可能只是在掩饰它。

10-08 03:38