Is there a way to implement a lock in Python for multithreading purposes whose acquire method can have an arbitrary timeout? The only working solutions I found so far use polling, which
Is there a better way to implement this?
Using Lock to prevent the race condition To prevent race conditions, you can use the Lock class from the threading module. A lock has two states: locked and unlocked. By default, the lock has the unlocked status until you acquire it.
A lock can be locked using the acquire() method. Once a thread has acquired the lock, all subsequent attempts to acquire the lock are blocked until it is released. The lock can be released using the release() method. Calling the release() method on a lock, in an unlocked state, results in an error.
Applying timeout function using thread in PythonThe first thread is to execute the function. 2. The second thread is to measure the time taken by the function. The only second thread should whether the time is over or not.
You can lock a variable to make it thread-safe using a threading. Lock. In this tutorial you will discover how to lock a variable in Python.
to elaborate on Steven's comment suggestion:
import threading import time  lock = threading.Lock() cond = threading.Condition(threading.Lock())  def waitLock(timeout):     with cond:         current_time = start_time = time.time()         while current_time < start_time + timeout:             if lock.acquire(False):                 return True             else:                 cond.wait(timeout - current_time + start_time)                 current_time = time.time()     return False   Things to notice:
threading.Lock() objects, one is internal to the threading.Condition().  cond, it's lock is acquired; the wait() operation unlocks it, though, so any number of threads can watch it.threading.Condition can become notified for reasons other than timeouts, so you still need to track the time if you really want it to expire.waitLock function should follow a lock.release() with a cond.notify() so that other threads waiting on it are notified that they should retry aquiring the lock.  This is not shown in the example.My version using thread safe queues http://docs.python.org/2/library/queue.html and their put/get methods that supports timeout.
Until now is working fine, but if someone can do a peer review on it I'll be grateful.
""" Thread-safe lock mechanism with timeout support module. """  from threading import ThreadError, current_thread from Queue import Queue, Full, Empty   class TimeoutLock(object):     """     Thread-safe lock mechanism with timeout support.     """      def __init__(self, mutex=True):         """         Constructor.         Mutex parameter specifies if the lock should behave like a Mutex, and         thus use the concept of thread ownership.         """         self._queue = Queue(maxsize=1)         self._owner = None         self._mutex = mutex      def acquire(self, timeout=0):         """         Acquire the lock.         Returns True if the lock was succesfully acquired, False otherwise.          Timeout:         - < 0 : Wait forever.         -   0 : No wait.         - > 0 : Wait x seconds.         """         th = current_thread()         try:             self._queue.put(                 th, block=(timeout != 0),                 timeout=(None if timeout < 0 else timeout)             )         except Full:             return False          self._owner = th         return True      def release(self):         """         Release the lock.         If the lock is configured as a Mutex, only the owner thread can release         the lock. If another thread attempts to release the lock a         ThreadException is raised.         """         th = current_thread()         if self._mutex and th != self._owner:             raise ThreadError('This lock isn\'t owned by this thread.')          self._owner = None         try:             self._queue.get(False)             return True         except Empty:             raise ThreadError('This lock was released already.') 
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With