2013-10-19 12 views
6

Mam wątek, który uruchomiłem (kod poniżej), który uruchamia podproces blokujący. Aby upewnić się, że inne wątki nie uruchamiają tego samego podprocesu, mam blokadę wokół tego połączenia subprocess.call. Chcę również móc zakończyć to wywołanie podprocesu, więc mam funkcję stop, którą wywołuję z innego miejsca. W przypadku, gdy podproces jest zatrzymany przedwcześnie, chcę, aby zwolnić blokadę, a także, co jest, co poniżej kodu:Zapytanie, czy wątek w Pythonie jest blokowany. Blokada jest zablokowana lub nie.

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

Jednakże, zgodnie z dokumentacją here, nazywając release() na zwolnionym blokady podniesie wyjątek:

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

Czy istnieje funkcja zapytań jak aLock.isLocked()?

Odpowiedz

22

Pewnie!

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

Można również zrobić posiadły non-blocking:

x.acquire(False) 
x.release() 

w takim przypadku, jeśli x został odblokowany kod nabywa go i uwalnia. Ale jeśli x był już zablokowany, przejęcie nieblokujące powraca natychmiast (i zwraca False), a my ponownie je zwalniamy. Ale to zależy od ras! Nic nie powstrzyma innego wątku przed zwolnieniem blokady między tymi dwoma liniami.

Ditto do sprawdzania .locked(). To tylko informuje cię o stanie blokady w czasie, gdy został wykonany .locked(). Może to już nie być prawdą, gdy wykonasz następną instrukcję.

Nawiasem mówiąc, ciało run() jest lepiej napisany przy użyciu blokadę jako „kierownik kontekstowego”, tak:

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

robi acquire()/release() parę dla siebie, i jest znacznie bardziej odporna na nieoczekiwane wyjątki podniesione w ciele bloku with (Python robi wszystko, aby zwolnić blokadę, jeśli ciało zostało wychodzące z powodu jakikolwiek powód).

+2

To jak początek ... musimy iść głębiej – puk

Powiązane problemy