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
答案 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
,因此如果它没有锁定它,它就无法作为条件。
作为旁注,获得Lock
和Condition
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()