5

In Java tryLock(long time, TimeUnit unit) can be used as a non-blocking attempt to acquire the lock. How can the equivalent in python be achieved? (Pythonic | idiomatic way is preferred!)

Java tryLock:

ReentrantLock lock1 = new ReentrantLock()
if (lock1.tryLock(13, TimeUnit.SECONDS)) { ... }

Python Lock:

import threading
lock = Lock()
lock.acquire() # how to lock.acquire(timeout = 13) ?
Community
  • 1
  • 1
n611x007
  • 8,952
  • 8
  • 59
  • 102
  • related ? http://stackoverflow.com/questions/8392640/how-to-implement-a-lock-with-a-timeout-in-python-2-7 – n611x007 Jun 13 '13 at 14:34

2 Answers2

7

The "try lock" behaviour can be obtained using threading module's Lock.acquire(False) (see the Python doc):

import threading
import time

my_lock = threading.Lock()
successfully_acquired = my_lock.acquire(False)
if successfully_acquired:
    try:
        print "Successfully locked, do something"
        time.sleep(1)
    finally:
        my_lock.release()
else:
    print "already locked, exit"

I can't figure out a satisfactory way to use with here.

Mathias
  • 309
  • 3
  • 12
2

Ouch, my bad! I should have read the python reference for Locks to begin with!

Lock.acquire([blocking])

When invoked with the blocking argument set to False, do not block. If a call with blocking set to True would block, return False immediately; otherwise, set the lock to locked and return True.

So I can just do something like this (or something more advanced even :P ):

import threading
import time

def my_trylock(lock, timeout):
    count = 0
    success = False
    while count < timeout and not success:
        success = lock.acquire(False)
        if success:
            break
        count = count + 1
        time.sleep(1) # should be a better way to do this
    return success

lock = threading.Lock()
my_trylock(lock, 13)
n611x007
  • 8,952
  • 8
  • 59
  • 102