查询Python的threading.Lock是否被锁定

puk*_*puk 13 python multithreading locking thread-safety

我有一个我正在运行的线程(下面的代码),它启动了一个阻塞子进程.为了确保其他线程不启动相同的子进程,我可以锁定此subprocess.call调用.我也希望能够终止这个子进程调用,所以我有一个stop函数,我从其他地方调用.如果子进程过早停止,我也想释放锁,这是下面的代码所做的:

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()
Run Code Online (Sandbox Code Playgroud)

但是,根据此处的文档,调用release()已释放的锁将引发异常:

A RuntimeError is raised if this method is called when the lock is unlocked.
Run Code Online (Sandbox Code Playgroud)

有查询功能aLock.isLocked()吗?

Tim*_*ers 34

当然!

>>> from threading import Lock
>>> x = Lock()
>>> x.locked()
False
>>> x.acquire()
True
>>> x.locked()
True
Run Code Online (Sandbox Code Playgroud)

您还可以进行非阻塞获取:

x.acquire(False)
x.release()
Run Code Online (Sandbox Code Playgroud)

在这种情况下,如果x解锁,代码将获取并释放它.但是如果x已经锁定,非阻塞获取立即返回(并返回False),我们再次释放它.但那是受比赛影响的!没有什么可以阻止其他线程释放这两行之间的锁定.

同样检查.locked().这只会告诉你当时锁的.locked()执行状态.执行下一个语句时可能不再是真的.

顺便说一句,run()使用锁作为"上下文管理器"更好地编写正文,如下所示:

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

acquire()/release()为你做对,并且对with块中体内出现的意外异常更加强大(如果因任何原因退出正文,Python会尽其所能释放锁).

  • 那么为什么不[文档](https://docs.python.org/2/library/threading.html#lock-objects)提到`locked()`函数? (8认同)
  • 这就像开始......我们必须更深入 (2认同)