如何判断Python的multiprocessing.Lock是否已释放?
>>> l = Lock()
>>> l.acquire()
True
>>> l.release()
>>> l.release()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: semaphore or lock released too many times
抛出了一个ValueError异常。我该如何防止锁被释放超过一次呢?有没有类似l.is_released()这样的检查方法?
4 个回答
2
创建一个简单的包装函数来进行检查:
from multiprocessing import Lock
l = Lock()
def is_locked():
locked = l.acquire(block=False)
if locked == False:
return True
else:
l.release()
return False
7
大家的想法是,获取了锁的地方应该知道什么时候该释放这个锁。那在什么情况下你会尝试多次释放这个锁呢?
9
这个问题有点不太清楚。你要么需要用信号量代替锁,要么检查一下锁是否被锁住了。
Python的锁和.Net上的锁是不一样的。Python的锁一旦解锁,就会释放所有在这个锁上等待的其他线程,让它们同时继续运行。也就是说,任何线程都可以解锁,所有等待的线程都会同时被放行。所以,不用再做第二次解锁,直接用下面的代码就可以了:
if l.locked():
l.release()
如果你想要“队列”的效果,也就是只有一个线程能在另一个线程释放锁后获得锁的控制权,那就应该使用信号量、事件或者其他类似的类,这些类可以支持嵌套锁定和排队的行为。
有趣的是,其他语言或工具,比如.Net,原生就支持锁的排队,也就是说线程可以按照顺序排队请求锁,阻塞并按照请求的顺序获得锁,而不是一次性释放所有线程。
(编辑:忘了加上括号,比如“如果 l.locked: l.release()”。已经修正了代码。Lock.locked这个方法在cPython 2.6.x、3.x和IronPython 2.6.1中都是存在的。)