Specifying `blocking` and `timeout` when acquiring lock as a context manager

Chris Kaynor ckaynor at zindagigames.com
Fri Aug 8 15:07:30 EDT 2014


On Fri, Aug 8, 2014 at 11:35 AM, Neil D. Cerutti <neilc at norwich.edu> wrote:

> On 8/8/2014 12:16 PM, Chris Angelico wrote:
>
>> On Sat, Aug 9, 2014 at 2:05 AM, Neil D. Cerutti <neilc at norwich.edu>
>> wrote:
>>
>>> Perhaps defer release, a la a common Go pattern:
>>>
>>> with contextlib.ExitStack() as stack:
>>>      acquired = lock.acquire(blocking=False)
>>>      if acquired:
>>>          stack.callback(lock.release)
>>>          do_stuff
>>>
>>
>> There's a race condition in that - an unexpected exception could
>> happen between those two. Are you able to set the callback to be a
>> "release if acquired" atomic operation?
>>
>
> Doesn't any natural looking use of blocking=False suffer from the same
> race condition? What's the correct way to use it?
>
> Here's another attempt at context managing:
>
> @contextlib.contextmanager
> def release_if_acquired(lock, blocking=True, timeout=-1):
>     acquired = lock.acquire(blocking, timeout)
>     if acquired:
>         yield acquired
>         lock.release()
>     else:
>         yield acquired
>

What I'd probably do is:
@contextlib.contextmanager
def release_if_acquired(lock, blocking=True, timeout=-1):
    acquired = lock.acquire(blocking, timeout)
    try:
        yield acquired
    finally:
        if acquired:
            lock.release()

However, there is still the chance that a interrupt signal (ctrl+c) could
prevent the lock from being released, but I think the only 100% solution
would be to write the code in C where it cannot be interrupted within
Python. The OS could still interrupt or kill the thread, but in that case,
I don't think there is anything you can do...


> with release_if_acquired(lock, blocking=False) as acquired:
>     if acquired:
>
>         do_stuff
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20140808/375bd255/attachment.html>


More information about the Python-list mailing list