2010-01-18 4 views
35

Ich benutze pthread_create(&thread1, &attrs, //... , //...); und brauchen, wenn eine Bedingung aufgetreten ist, diesen Thread zu töten, wie dies zu töten?Kill Thread in Pthread Bibliothek

Antwort

50

erste Laden der Thread-ID

pthread_create(&thr, ...) 

dann rufen Sie später

pthread_cancel(thr) 

Dies ist jedoch nicht eine empfohlene Programmierstil! Es ist besser, einen Inter-Thread-Kommunikationsmechanismus wie Semaphoren oder Nachrichten zu verwenden, um mit dem Thread zu kommunizieren, dass er die Ausführung stoppen sollte.

Beachten Sie, dass pthread_kill (...) den empfangenden Thread nicht tatsächlich beendet, sondern stattdessen ein Signal an ihn sendet, und es hängt vom Signal- und Signalhandler ab, was passiert.

+4

Das Problem mit Pthread_cancel, BTW, ist, dass, wenn Sie es verwenden, dann der Code in dem Thread ausgeführt wird, der abgebrochen wird, muss Stornierungspunkte zu verstehen, und stellen Sie sicher, dass (a) es häufig genug trifft, dass es tatsächlich abgebrochen wird Zeit, und (b) es gibt keine Ressourcen aus, wenn dies geschieht. Das ist etwas schwierig, wenn Sie eine Nachricht verwenden, dann ist es genau in Ihrem Code genau, wenn der Thread beendet werden kann. –

+11

@Steve: Unglücklicherweise ist 'pthread_cancel' die einzige saubere Methode * im Bibliothekscode *, um einen Thread zu unterbrechen, der auf einem Syscall blockiert sein könnte. Die andere Methode besteht darin, einen unterbrechenden Signalhandler zu installieren und sicherzustellen, dass Ihr gesamter Code bereit ist, mit EINTR umzugehen, aber Bibliothekscode kann nicht davon ausgehen, dass er das Signalhandling ändern oder dem Aufrufer eine EINTR-Behandlung auferlegen kann. –

2

Schauen Sie sich die Funktion an.

+2

Dies tötet keinen Thread, es sendet nur ein Signal. – alk

5

Ich stimme mit Antti überein, bessere Praxis wäre, einige Prüfpunkte zu implementieren, wo der Thread prüft, ob es beendet werden sollte. Diese Prüfpunkte können auf verschiedene Arten implementiert werden, z. B .: eine gemeinsam genutzte Variable mit Sperre oder ein Ereignis, bei dem der Thread prüft, ob er gesetzt ist (der Thread kann entscheiden, auf Null zu warten).

18

Es gibt zwei Ansätze für dieses Problem.

  • Verwenden eines Signal: Das Gewinde installiert eine Signalbehandlungsroutine sigaction() verwendet, die eine Flagge setzt, und der Faden überprüft periodisch das Flag, um zu sehen, ob es beenden muss. Wenn der Thread beendet werden muss, geben Sie das Signal an und warten Sie auf seine Beendigung mit pthread_join(). Dieser Ansatz erfordert eine Vorsynchronisierung zwischen dem übergeordneten Thread und dem untergeordneten Thread, um zu gewährleisten, dass der untergeordnete Thread den Signalhandler bereits installiert hat, bevor er das Beendigungssignal verarbeiten kann.
  • Verwenden Sie einen Abbruchpunkt: Der Thread wird beendet, sobald eine Abbruchfunktion ausgeführt wird. Wenn der Thread beendet werden muss, führen Sie pthread_cancel() aus und warten Sie auf seine Beendigung mit pthread_join(). Dieser Ansatz erfordert eine detaillierte Verwendung von pthread_cleanup_push() und pthread_cleanup_pop(), um Ressourcenverlust zu vermeiden. Diese letzten zwei Aufrufe könnten sich mit dem lexikalischen Umfang des Codes befassen (da sie Makros sein können, die { und } Tokens ergeben) und sind sehr schwierig richtig zu warten.

(Beachten Sie, dass, wenn Sie bereits den Faden mit pthread_detach() abgelöst haben, können Sie es wieder pthread_join() mit nicht beitreten können.)

Beide Ansätze sehr schwierig sein kann, aber entweder könnte in einer bestimmten Situation besonders nützlich sein.

0
pthread_exit(0) 

Dies wird den Thread beenden.