1000 Stimmen

Gibt es eine Möglichkeit, einen Thread zu löschen?

Ist es möglich, einen laufenden Thread zu beenden, ohne irgendwelche Flags/Semaphoren/etc. zu setzen/zu überprüfen?

7voto

snyh Punkte 1135
from ctypes import *
pthread = cdll.LoadLibrary("libpthread-2.15.so")
pthread.pthread_cancel(c_ulong(t.ident))

t ist Ihr Thread Objekt.

Lesen Sie den Python-Quelltext ( Modules/threadmodule.c y Python/thread_pthread.h ) können Sie die Thread.ident ist ein pthread_t Typ, so dass Sie alles tun können pthread in Python tun können, verwenden Sie libpthread .

4voto

Chema Punkte 91

Eine Sache, die ich hinzufügen möchte, ist, dass, wenn Sie die offizielle Dokumentation in threading lib Python Es wird empfohlen, die Verwendung von "dämonischen" Fäden zu vermeiden, wenn man nicht will, dass Fäden abrupt enden, mit dem Hinweis, dass Paolo Rovelli erwähnt .

Aus der offiziellen Dokumentation:

Daemon-Threads werden beim Herunterfahren abrupt beendet. Ihre Ressourcen (wie offene Dateien, Datenbanktransaktionen usw.) werden möglicherweise nicht ordnungsgemäß freigegeben. Wenn Sie möchten, dass Ihre Threads ordnungsgemäß beendet werden, machen Sie sie zu nicht-dämonischen Threads und verwenden Sie einen geeigneten Signalisierungsmechanismus wie z. B. ein Ereignis.

Ich denke, dass das Erstellen von daemonischen Threads von Ihrer Anwendung abhaengt, aber im Allgemeinen (und meiner Meinung nach) ist es besser, sie nicht zu toeten oder sie daemonisch zu machen. Im Multiprocessing können Sie Folgendes verwenden is_alive() um den Status von Prozessen zu überprüfen und sie mit "terminate" zu beenden (auch um GIL-Probleme zu vermeiden). Aber Sie können mehr Probleme finden, manchmal, wenn Sie Ihren Code in Windows ausführen.

Und denken Sie immer daran, dass, wenn Sie "Live-Threads" haben, der Python-Interpreter läuft, um sie zu warten. (Wegen dieser daemonischen kann Ihnen helfen, wenn don't Materie abrupt endet).

4voto

Jason R. Coombs Punkte 38667

Zu diesem Zweck wurde eine Bibliothek eingerichtet, stopit . Auch wenn einige der hier aufgeführten Vorsichtsmaßnahmen nach wie vor gelten, bietet diese Bibliothek zumindest eine regelmäßige, wiederholbare Technik, um das erklärte Ziel zu erreichen.

3voto

Tim Meehan Punkte 131

Nur um auf @SCBs Idee aufzubauen (die genau das war, was ich brauchte), eine KillableThread-Unterklasse mit einer angepassten Funktion zu erstellen:

from threading import Thread, Event

class KillableThread(Thread):
    def __init__(self, sleep_interval=1, target=None, name=None, args=(), kwargs={}):
        super().__init__(None, target, name, args, kwargs)
        self._kill = Event()
        self._interval = sleep_interval
        print(self._target)

    def run(self):
        while True:
            # Call custom function with arguments
            self._target(*self._args)

            # If no kill signal is set, sleep for the interval,
            # If kill signal comes in while sleeping, immediately
            #  wake up and handle
            is_killed = self._kill.wait(self._interval)
            if is_killed:
                break

        print("Killing Thread")

    def kill(self):
        self._kill.set()

if __name__ == '__main__':

    def print_msg(msg):
        print(msg)

    t = KillableThread(10, print_msg, args=("hello world"))
    t.start()
    time.sleep(6)
    print("About to kill thread")
    t.kill()

Wie bei @SBC wartet der Thread natürlich nicht darauf, dass eine neue Schleife läuft, um anzuhalten. In diesem Beispiel würden Sie die Meldung "Killing Thread" direkt nach der Meldung "About to kill thread" sehen, anstatt 4 weitere Sekunden auf den Abschluss des Threads zu warten (da wir bereits 6 Sekunden geschlafen haben).

Das zweite Argument im KillableThread-Konstruktor ist Ihre eigene Funktion (hier print_msg). Args-Argument sind die Argumente, die beim Aufruf der Funktion (("hello world")) hier verwendet werden.

2voto

reubano Punkte 4501

Eine Alternative ist die Verwendung von signal.pthread_kill um ein Stoppsignal zu senden.

from signal import pthread_kill, SIGTSTP
from threading import Thread
from itertools import count
from time import sleep

def target():
    for num in count():
        print(num)
        sleep(1)

thread = Thread(target=target)
thread.start()
sleep(5)
pthread_kill(thread.ident, SIGTSTP)

Ergebnis

0
1
2
3
4

[14]+  Stopped

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X