2013-08-24 10 views
7

Spędziłem ostatnią godzinę (s ???) szukając/szukając sposobu, aby klasa zaczęła jedną z jej metod w nowym wątku, gdy tylko zostanie zainicjowana.Instancja klasy Python rozpoczyna metodę w nowym wątku

mogę uruchomić coś takiego:

x = myClass() 

def updater(): 
    while True: 
     x.update() 
     sleep(0.01) 

update_thread = Thread(target=updater) 
update_thread.daemon = True 
update_thread.start() 

bardziej eleganckim sposobem byłoby mieć klasę robi to w init, gdy jest instanciated. Wyobraź sobie, że masz 10 wystąpień tej klasy ... Do tej pory nie mogłem znaleźć (działającego) rozwiązania dla tego problemu ... Właściwą klasą jest licznik czasu, a metoda jest metodą aktualizacji, która aktualizuje wszystkie zmienne licznika . Ponieważ ta klasa musi również uruchamiać funkcje w danym czasie, ważne jest, aby aktualizacje czasu nie były blokowane przez główny wątek.

Każda pomoc jest doceniana. Thx z góry ...

+1

Jaki problem napotkałeś, próbując umieścić ten kod w 'MyClas .__ init__'? – user4815162342

Odpowiedz

14

Można podklasy bezpośrednio z nici w tym konkretnym przypadku

from threading import Thread 

class MyClass(Thread): 
    def __init__(self, other, arguments, here): 
     super(MyClass, self).__init__() 
     self.daemon = True 
     self.cancelled = False 
     # do other initialization here 

    def run(self): 
     """Overloaded Thread.run, runs the update 
     method once per every 10 milliseconds.""" 

     while not self.cancelled: 
      self.update() 
      sleep(0.01) 

    def cancel(self): 
     """End this timer thread""" 
     self.cancelled = True 

    def update(self): 
     """Update the counters""" 
     pass 

my_class_instance = MyClass() 

# explicit start is better than implicit start in constructor 
my_class_instance.start() 

# you can kill the thread with 
my_class_instance.cancel() 
+0

Pokonaj mnie pół minuty. +1 dla dobrej odpowiedzi. Powinieneś prawdopodobnie dołączyć przynajmniej sygnaturę dla metody aktualizacji, ponieważ twoja odpowiedź wygląda na to, że powinna być kompletnym działaniem kodu. Ponadto pomija instrukcję importu dla "uśpienia". – Henrik

+0

Działa to jak urok ... Czasami rozwiązanie jest niezwykle proste. Miałem podobne podejście, ale nie mogłem go uruchomić. Wielkie dzięki ... Czasami po prostu nie widzę drewna dla drzew. – hegoe

2

w celu uruchomienia funkcji (lub memberfunction) w wątku, użyj tego:

th = Thread(target=some_func) 
th.daemon = True 
th.start() 

Porównywanie tego z wywodem z Thread ma tę zaletę, że nie eksportuje wszystkich publicznych funkcji wątku jako własnych publicznych funkcji. W rzeczywistości nie musisz nawet pisać klasy, aby korzystać z tego kodu, self.function lub global_function są w równym stopniu użyteczne jako target tutaj.

Chciałbym również rozważyć użycie menedżera kontekstu do uruchamiania/zatrzymywania wątku, w przeciwnym razie wątek może pozostać przy życiu dłużej niż to konieczne, prowadząc do przecieków zasobów i błędów podczas zamykania. Ponieważ umieszczasz to w klasie, uruchom wątek w __enter__ i dołącz do niego w __exit__.

Powiązane problemy