Python线程锁是condition.acquire,类似于lock.acquire

时间:2018-03-27 06:25:46

标签: python multithreading

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

2 个答案:

答案 0 :(得分:2)

如果您的条件是这样创建的:

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 s 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解决了什么问题,你可能只是伪装它。

答案 1 :(得分:2)

代码的通知部分如下。

print "count is %d %s" % (count[ipID],name)

   cond.acquire()

   count[ipID] = count[ipID] - 1
   cond.notifyAll()
   cond.release()