Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python equivalent of Java's `tryLock` (idiomatic)?

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) ?
like image 521
n611x007 Avatar asked Jun 13 '13 13:06

n611x007


2 Answers

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.

like image 107
Mathias Avatar answered Sep 20 '22 06:09

Mathias


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)
like image 31
n611x007 Avatar answered Sep 22 '22 06:09

n611x007