views:

52

answers:

2
>>> 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() ?

+5  A: 

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?

Jeremy Brown
A: 

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)

ddotsenko
>>> from multiprocessing import Lock>>> Lock().lockedTraceback (most recent call last): File "<stdin>", line 1, in <module>AttributeError: 'Lock' object has no attribute 'locked'
Juanjo Conti