2012-07-11 17 views
33

Co próbuję tutaj zrobić, użyj przerwania klawiatury, aby zamknąć wszystkie bieżące wątki w programie. Jest to pominięto w wersji mojego kodu, gdzie wątek jest tworzony:Zamykanie wszystkich wątków z przerwaniem klawiatury

for i in taskDictionary: 
    try: 
     sleep(60) 
     thread = Thread(target = mainModule.executeThread) 
     thread.start() 
    except KeyboardInterrupt: 
     thread.__stop() 

Sam program jest znacznie bardziej skomplikowana, co stanowi ton różnych zmiennych, które wpływają na wątki, a nawet o możliwość uruchomienia w sekwencyjnym Tryb, w którym zadania nie są nawiązywane, ale uruchamiane pojedynczo, więc mogą pojawić się problemy z tą małą odmianą, którą właśnie wywołałem. Zrobiłem to w sposób, który przyniósł 50/50 wyników. Przerwania zadziałają, ale nici nigdy nie wyjdą. Czasami kontynuowali, ale powstrzymywali wykonywanie przyszłych wątków, czasami wychodzili z ogromnym błędem dotyczącym przerwania, innym razem przerywani nie robili nic. Ostatnim razem, gdy to uruchomiłem, program zatrzymał wszelkie przyszłe wątki, ale nie zatrzymał bieżącego wątku. Czy istnieje sposób na wyjście z wątków bez wchodzenia do modułu, w którym wątek faktycznie wykonuje?

Odpowiedz

52

Podobnym pytaniem jest "Jak zabić nitkę?"

Tworzysz obsługę wyjścia w swoim wątku, który jest kontrolowany przez blokadę lub obiekt zdarzenia z modułu wątków. Następnie wystarczy usunąć blokadę lub zasygnalizować obiekt zdarzenia. To informuje wątek, że powinien przestać przetwarzać i wyjść z wdziękiem. Po sygnalizowaniu wątku w programie głównym, jedyne co można zrobić, to użyć metody thread.join() w main, która będzie czekać na zamknięcie wątku.

Krótki przykład:

import threading 
import time 

def timed_output(name, delay, run_event): 
    while run_event.is_set(): 
     time.sleep(delay) 
     print name,": New Message!" 


def main(): 
    run_event = threading.Event() 
    run_event.set() 
    d1 = 1 
    t1 = threading.Thread(target = timed_output, args = ("bob",d1,run_event)) 

    d2 = 2 
    t2 = threading.Thread(target = timed_output, args = ("paul",d2,run_event)) 

    t1.start() 
    time.sleep(.5) 
    t2.start() 

    try: 
     while 1: 
      time.sleep(.1) 
    except KeyboardInterrupt: 
     print "attempting to close threads. Max wait =",max(d1,d2) 
     run_event.clear() 
     t1.join() 
     t2.join() 
     print "threads successfully closed" 

if __name__ == '__main__': 
    main() 

Jeśli naprawdę potrzebujesz funkcjonalności zabijania wątku, użyj wieloprocesorowe. Umożliwia wysyłanie SIGTERM-ów do poszczególnych "procesów" (jest to bardzo podobne do modułu wątków). Ogólnie rzecz biorąc, wątkowanie jest dla, gdy jesteś związany z IO, a wieloprocesorowość jest, gdy jesteś naprawdę związany z procesorem.

+7

Dzięki współpracy z wątkiem możesz zabić go w dowolny sposób. Bez współpracy z nicią nie ma bezpiecznej drogi, a wszystkie drogi prowadzą do bólu. –

+1

Wspaniała odpowiedź! Nie dokładnie to, czego szukałem, ale wystarczająco obszerne, że byłem w stanie dostosować logikę do tego, czego potrzebowałem! Dziękuję za to! – Joe

+1

Używam wątku, ponieważ nie chcę nieskończonej pętli True. To marnuje cały czas procesora ... dosłownie. Zrobiłem coś takiego i bez snu to procesor CPU% do 100% na ** sekundy ** na raz i przy małym śnie, to tylko trochę pomaga. Czy jest jakiś sposób na zrobienie tego ** bez ** a while True? – dylnmc

Powiązane problemy