ein Kapitel zurück                                           ein Kapitel weiter

Kommen wir nun zu weiteren nützlichen Threadfunktionen. Zur Beendigung einzelner Threads, außer mit return oder pthread_exit, gibt es folgende Funktion.....

int pthread_cancel(phtread_t thread);  

Hiermit wird der Thread mit der ID von thread beendet abhängig von folgenden Punkten....
Abbruchstatus
Die default-Einstellung dieses Statuses ist PTHREAD_CANCEL_ENABLE was bedeutet, das der Abbruch des Threads aus einem zweiten Thread erlaubt ist. Wenn sie die Konstante PTHREAD_CANCEL_DISABLE setzen unterbinden sie dies. Setzen können sie diese beiden Konstanten mit der Funktion.......

int pthread_setcancelstate(int state, int *oldstate);  

Schauen wir uns das ganze mal in der Praxis an.........

/*Download:thread12.c*/
#include <stdio.h> #include <pthread.h> #include <asm/errno.h> #include <stdlib.h> #include <time.h> pthread_t t1,t2,t3; int zufallszahl; void cancel_test1() { if(zufallszahl>25) { pthread_cancel(t3); printf("%d : Habe \"THREAD2\" beendet!\n",zufallszahl); } printf("TREAD1 zuende\n"); pthread_exit((void*)0); } void cancel_test2() { if(zufallszahl<=25) { pthread_cancel(t2); printf("%d : Habe \"THREAD1\" beendet!\n",zufallszahl); } printf("THREAD2 zuende\n"); pthread_exit((void*)0); } void zufall(void) { srand(time(NULL)); zufallszahl=rand()%50; pthread_exit(NULL); } int main() { if((pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL)) !=0) { fprintf(stderr,"Fehler bei pthread_setcancelstate.......\n"); exit(0); } if((pthread_create(&t1, NULL, (void *)&zufall, NULL)) !=0) { fprintf(stderr, "Fehler bei ptread_create.........\n"); exit(0); } if((pthread_create(&t2, NULL, (void *)&cancel_test1, NULL)) !=0) { fprintf(stderr, "Fehler bei ptread_create.........\n"); exit(0); } if((pthread_create(&t3, NULL, (void *)&cancel_test2, NULL)) !=0) { fprintf(stderr, "Fehler bei ptread_create.........\n"); exit(0); } return 0; }

Wir erzeugen hier 3 Threads. Einer erzeugt eine Zufallszahl die anderen zwei Threads reagieren entsprechend auf die Zufallszahl. Je nach dem ob die die Zufallszahl kleiner bzw. größer als 25 sind beendet der eine Thread den anderen mit pthread_cancel. Wenn sie das Programm ausführen wird trotzdem nach Beendigung eines der beiden Threads mit pthread_cancel zweimal ausgegeben.........

Threadn beendet  

Wie kann das sein wo sie doch mindestens einen Thread beendet habe? Nun das ist die 2. Bedienung zur Beendigung von Threads. Nämlich die Reaktion auf Abbruchsanforderungen. Die default-Einstellung lautet hier nämlich PTHREAD_CANCEL_DEFERRED. Damit läuft der Thread nochein mal bis zum nächsten Abbruchspunkt. In unserem Fall pthread_exit. Wenn sie einen Thread sofort abbrechen wollen bzw. müssen, benötigen sie die Konstante PTHREAD_CANCEL_ASYNCHRONOUS Diese beiden Konstanten können sie mit der Funktion.........

int pthread_setcanceltype(int type, int *oldtype);  

...setzen. Wollen wir das wieder in unser Programm einbauen..........

if((pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) != 0)
{
  fprintf(stderr, "Fehler bei pthread_setcanceltype..........\n");
  exit(0);
}  

Schreiben sie dies in die main-Funktion. Ich muss Anmerken das diese Funktion pthread_setcanceltype sobald wie möglich abbricht. Aus diesem Grund kann es schon passieren das in unserem Beispiel dennoch beide Funktionen bis zum Schluss ausgeführt werden. Wollen wir uns noch ein Beispiel zu pthread_cancel ansehen.

Doch zuvor kommen wir noch schnell zur Fehlerbehandlung von Threads. Alle Threadfunktionen geben falls sie ohne Fehler gelaufen sind 0 zurück. Ansonsten einen positiven Wert aber niemals -1. Also könnten wir eine Funktion definieren die für alle Threads gültig ist. Auf der Suche im Internet zu den Threads habe ich dabei folgende Funktion gefunden...

void checkResults(string, val) {
    if (val) {
      printf("Failed with %d at %s", val, string);
      exit(1);
    }
}  

Nehmen wir gleich nochmals unser Beispiel zuvor zum Aufrufen dieser Funtkion.....

int status;
..............
status=pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
checkResults("pthread_setcancelstate()",status);  

Dies sieht doch schon besser aus oder? Die Funktion wird auch nur Ausgeführt wenn der status ungleich 0 ist, also bei Fehler. Hier nun das Beispiel.......

/*Download:thread13.c*/
#include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> /*Fehlerbeendigung für alle Threads*/ void checkResults(string, val) { if (val) { printf("Failed with %d at %s", val, string); exit(1); } } void *theThread(void *parm) { printf("Thread: Anfang\n"); while (1) { printf("Thread: In der Schleife und wartet auf Anfrage\n"); pthread_testcancel(); sleep(1); } return NULL; } int main(int argc, char **argv) { pthread_t thread; int rc=0; void *status; printf("Beginne Test - %s\n", argv[0]); printf("Create/startet einen thread\n"); rc = pthread_create(&thread, NULL, theThread, NULL); checkResults("pthread_create()\n", rc); printf("Wir warten ein bißchen bis wir unseren Thread wieder beenden\n"); sleep(3); rc = pthread_cancel(thread); checkResults("pthread_cancel()\n", rc); printf("Wir warten bis unser Thread fertig ist und die Ressourcen freigibt\n"); rc = pthread_join(thread, &status); checkResults("pthread_join()\n", rc); printf("Thread zeigt an das er fertig ist\n"); if (status != PTHREAD_CANCELED) { printf("Unexpected thread status\n"); } printf("Main completed\n"); return 0; }

Dies Programm dürfte eigentlich selbsterklärend und nicht schwer zu verstehen sein.

Signale und Threads

Das das Signal SIGKILL alle Threads auf einmal beendet dürfte wohl klar sein. Dies gilt auch für die Funktion.....

int pthread_kill(pthread_t th, int sig);  

Wollen sie einem bestimmten Thread ein Signal senden können sie dies mit der Funktion.........

int pthread_sigmask(int how, const sigset_t *newmask, sigset_t *oldmask)  

Mehr zu den Signalen und Threads finden sie unter.....

man pthread_kill
man pthread_sigmask
man sigwait  

Allgemein emfehle ich Ihnen zu den Threads in der man-Page nachzusehen. Dort finden sie noch eine Menge mehr dazu.

Dies waren jetzt natürlich nicht alle Funktionen zu der Thread-Programmierung mit der libpthread. Ich hoffe Ihnen damit etwas zur Threadprogrammierung beigebracht zu haben.

ein Kapitel zurück          nach oben           ein Kapitel weiter


© 2001,2002 Jürgen Wolf