开发者

How to know if a Python multiprocessing.Lock is released or not?

>>> 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

throws a ValueError exception. How can I prevent to release a lock more than once? Something like l.is_released() ?


The question is a bit unclear. You either need to use semaphores instead of locks or check if lock is locked.

Python's locks are not the same as locks on .Net, for example. Python's Lock once unlocks releases ALL other threads that acquired() on the same lock and blocked for the time being. Any thread can release and all go at the same time. So, instead of doing second relase, do

if l.locked():
    l.release()

If you want "queue" behavior, where only one tread will get ownership of a lock once some other releases, use Semaphore, Event or some other similar class that allows nested locking and queuing behavior.

It's interesting to note that other languages/loolkits, like .Net, do lock queuing natively, where threads can pile up lock.acquire in order, block and take ownership of the lock object in the order of acquire queue, not release all at once.

(Edit: forgot to put parents as in "if l.locked: l.realse()". Corrected the code. Lock.locked is confirmed to be a present method in cPython 2.6.x, 3.x, IronPython 2.6.1)


The expectation is that the context that acquired the lock should be aware of when it should release it. In what circumstance would you attempt to release it multiple times?


Create a quick wrapper function to check:

from multiprocessing import Lock

l = Lock()

def is_locked():
    locked = l.acquire(block=False)
    if locked == False:
        return True
    else:
        l.release()
        return False


Since lock.acquire() returns true if it successfully acquires the lock, you can store the state of locking in a local variable and then encapsulate lock.acquire() and the subsequent code inside a try-finally block. Then in the finally block, you can query the variable to see if the lock has been acquired or not. If it has, release.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜