Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Query whether Python's threading.Lock is locked or not

I have a thread I am running (code below) which launches a blocking subprocess. To ensure that other threads do not launch the same subprocess, I have a lock around this subprocess.call call. I also want to be able to terminate this subprocess call, so I have a stop function which I call from somewhere else. In the event that the subprocess is stopped prematurely, I want to release the lock as well, which is what the below code does:

class SomeThread(threading.Thread):
   def run(self):
      aLock.acquire()
      self.clip = subprocess.call([ 'mplayer', 'Avatar.h264'], stdin=subprocess.PIPE)
      aLock.release()
   def stop(self):
      if self.clip != None and self.clip.poll() == True:
         try:
            self.clip.send_signal(signal.SIGINT)
         except:
            pass
      aLock.release()

However, according to the documentation here, calling release() on a released lock will raise an Exception:

A RuntimeError is raised if this method is called when the lock is unlocked.

Is there a query function like aLock.isLocked()?

like image 681
puk Avatar asked Oct 19 '13 00:10

puk


People also ask

What is threading lock () in Python?

The condition occurs when one thread tries to modify a shared resource at the same time that another thread is modifying that resource – t​his leads to garbled output, which is why threads need to be synchronized. The threading module of Python includes locks as a synchronization tool. A lock has two states: locked.

What is the difference between threading lock and threading are lock?

A Lock object can not be acquired again by any thread unless it is released by the thread which is accessing the shared resource. An RLock object can be acquired numerous times by any thread. A Lock object can be released by any thread. An RLock object can only be released by the thread which acquired it.

Is Python threading really threading?

Python is NOT a single-threaded language. Python processes typically use a single thread because of the GIL. Despite the GIL, libraries that perform computationally heavy tasks like numpy, scipy and pytorch utilise C-based implementations under the hood, allowing the use of multiple cores.

Do Python threads close themselves?

In Python, any alive non-daemon thread blocks the main program to exit. Whereas, daemon threads themselves are killed as soon as the main program exits. In other words, as soon as the main program exits, all the daemon threads are killed.


1 Answers

Sure!

>>> from threading import Lock
>>> x = Lock()
>>> x.locked()
False
>>> x.acquire()
True
>>> x.locked()
True

You could also do a non-blocking acquire:

x.acquire(False)
x.release()

In this case, if x was unlocked then the code acquires it, and releases it. But if x was already locked, the non-blocking acquire returns at once (and returns False), and we again release it. But that's subject to races! There's nothing to stop some other thread from releasing the lock between those two lines.

Ditto for checking .locked(). That only tells you the state of the lock at the time .locked() was executed. It may no longer be true by the time you execute the next statement.

By the way, the body of run() is better written using the lock as a "context manager", like so:

def run(self):
    with aLock:
        self.clip = subprocess.call([ 'mplayer', 'Avatar.h264'], stdin=subprocess.PIPE)

This does the acquire()/release() pair for you, and is much more robust against unexpected exceptions raised in the body of the with block (Python does all it can to release the lock if the body is exited for any reason).

like image 51
Tim Peters Avatar answered Sep 28 '22 04:09

Tim Peters