2013-10-19 6 views
6

実行中のスレッド(以下のコード)が、ブロックするサブプロセスを起動しています。他のスレッドが同じサブプロセスを起動しないようにするには、このsubprocess.callコールの周りにロックがあります。私はまた、このサブプロセス呼び出しを終了することができるようにしたいので、私はどこからでも呼び出すstop関数を持っています。サブプロセスが途中で停止した場合には、私は以下のコードが何をするかであるだけでなく、ロックを解除したい:Pythonのthreading.Lockがロックされているかどうかを照会してください

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() 

をしかし、ドキュメンテーションhereによると、ロック解除にrelease()を呼び出して発生させます例外:

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

aLock.isLocked()ようなクエリ機能がありますか?

答えて

22

確かに!

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

あなたはまた、非ブロッキング取得行うことができます:xは、コードがそれを取得し、解放するロック解除された場合、その場合には

x.acquire(False) 
x.release() 

を。しかし、xがすでにロックされていた場合、ノンブロッキング取得は一度に戻り(Falseを返します)、再び解放します。しかし、それはレースの対象です!他のスレッドがロックを解除するのを止めるものは何もないとの間にある。

照合用.locked()。それは、時刻が実行されたときのロックの状態だけを示しています。あなたが次の声明を実行するときには、もはや真実ではないかもしれません。ところで

は、run()の本体は、より良いので、同じように、「コンテキストマネージャ」としてロックを使用して書かれている:

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

ザ・はあなたのためにacquire()/release()ペアを行い、そして予想外に対してはるかに堅牢ですwithブロックの本体で発生した例外(本体がのいずれかの理由で終了した場合、Pythonはすべてロックを解除できます)の理由)。

+2

これは始まりのようです...もっと深くする必要があります – puk

関連する問題