Wann sollte pthread_exit() und wann pthread_join() unter Linux verwendet werden?

Lesezeit: 8 Minuten

Benutzeravatar von dexterous
geschickt

Ich bin neu bei pthreads und versuche es zu verstehen. Ich habe einige Beispiele wie die folgenden gesehen.

Ich konnte sehen, dass die main() wird von der API blockiert pthread_exit()und ich habe Beispiele gesehen, bei denen die Hauptfunktion von der API blockiert wird pthread_join(). Ich kann nicht verstehen, wann ich was verwenden soll?

Ich beziehe mich auf die folgende Seite – https://computing.llnl.gov/tutorials/pthreads/. Ich bin nicht in der Lage, das Konzept zu verstehen, wann ich es verwenden soll pthread_join() und wann zu verwenden pthread_exit().

Kann jemand bitte erklären? Auch ein guter Tutorial-Link für pthreads wird geschätzt.

#include <pthread.h>
#include <stdio.h>
#define NUM_THREADS     5

void *PrintHello(void *threadid)
{
   long tid;
   tid = (long)threadid;
   printf("Hello World! It's me, thread #%ld!\n", tid);
   pthread_exit(NULL);
}

int main (int argc, char *argv[])
{
   pthread_t threads[NUM_THREADS];
   int rc;
   long t;
   for(t=0; t<NUM_THREADS; t++){
      printf("In main: creating thread %ld\n", t);
      rc = pthread_create(&threads
      if (rc){
         printf("ERROR; return code from pthread_create() is %d\n", rc);
         exit(-1);
      }
   }

   /* Last thing that main() should do */
   pthread_exit(NULL);

Eine weitere Sache wurde mir klar, dh

pthread_cancel(thread);
pthread_join(thread, NULL);

Manchmal möchten Sie den Thread während der Ausführung abbrechen. Sie könnten dies mit pthread_cancel(thread); tun. Denken Sie jedoch daran, dass Sie die pthread-Abbruchunterstützung aktivieren müssen. Außerdem ein Reinigungscode bei der Stornierung.

thread_cleanup_push(my_thread_cleanup_handler, resources);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);

static void my_thread_cleanup_handler(void *arg)
{
  // free
  // close, fclose
}

Benutzeravatar von Suvarna Pattayil
Suvarna Pattayil

Wie in den Openpub-Dokumentationen erklärt,

pthread_exit() beendet den Thread, der es aufruft.

In Ihrem Fall nennt es main, main Faden wird beendet, während Ihre erzeugten Threads weiterhin ausgeführt werden. Dies wird hauptsächlich in Fällen verwendet, in denen der Hauptthread nur Threads erzeugen und die Threads ihre Arbeit erledigen lassen muss

pthread_join

unterbricht die Ausführung des Threads, der ihn aufgerufen hat, es sei denn, der Ziel-Thread wird beendet

Dies ist nützlich, wenn Sie auf die Beendigung von Threads warten möchten, bevor Sie die Verarbeitung im Haupt-Thread fortsetzen.

  • Möglicherweise hat sich die Implementierung geändert, seit Sie diese Frage beantwortet haben. Laut der Seite, auf die sich Geschicklichkeit bezieht, wird main blockiert und am Leben erhalten, um die von ihm erstellten Threads zu unterstützen, bis sie fertig sind, indem main() explizit pthread_exit() als letztes aufruft. Das heißt, ein Thread kann nicht außerhalb des Hauptthreads main() leben.

    – oklm

    11. Dezember 2020 um 11:59 Uhr


Benutzeravatar von Alok Save
Alok Speichern

pthread_exit beendet den aufrufenden Thread while pthread_join setzt die Ausführung des aufrufenden Threads aus, bis der Ziel-Thread die Ausführung abgeschlossen hat.

Sie werden in der offenen Gruppendokumentation ziemlich gut im Detail erklärt:

  • Aber hast du das in main() gesehen, ich habe pthread_exit() aufgerufen. Dies blockiert die Beendigung von main() und lässt den Thread laufen und vervollständigen. Auf diese Weise ist es pthread_join() sehr ähnlich. Außerdem blockiert pthread_join() die Beendigung von main(), bis der Thread ausgeführt wird.

    – geschickt

    29. Dezember 2013 um 10:49 Uhr


  • Kennen Sie einen guten Link, um mit dem Verständnis von pthreads anzufangen?

    – geschickt

    29. Dezember 2013 um 10:51 Uhr

  • @BasileStarynkevitch, warum sollte es nicht. Dies ist ein gut definierter Anwendungsfall.

    – Jens Gustedt

    29. Dezember 2013 um 12:11 Uhr

Beide Methoden stellen sicher, dass Ihre Prozess endet nicht, bevor alle Ihre Threads beendet sind.

Die Join-Methode hat Ihren Thread von der main Funktion explizit auf alle Threads warten, die “beigetreten” werden sollen.

Das pthread_exit Methode beendet Ihre main kontrolliert funktionieren und einfädeln. main hat die Besonderheit, dass Ende main Andernfalls würde Ihr gesamter Prozess einschließlich aller anderen Threads beendet.

Damit dies funktioniert, müssen Sie sicherstellen, dass keiner Ihrer Threads lokale Variablen verwendet, die in ihnen deklariert sind main Funktion. Der Vorteil dieser Methode ist, dass Ihre main muss nicht alle Threads kennen, die in Ihrem Prozess gestartet wurden, zB weil andere Threads selbst neue Threads erstellt haben main weiß nichts davon.

  • Nicht sehr klar, sagen Sie, dass pthread_exit die Funktion main () blockiert, um sie zu beenden, damit der andere Thread funktioniert, eine Chance bekommt und gut funktioniert. Können Sie mir bitte einen guten Link zu pthreads nennen? Sieht so aus, als ob mir die Grundlagen fehlen.

    – geschickt

    29. Dezember 2013 um 12:57 Uhr

  • @SHREYASJOSHI, nein, es blockiert nicht main Funktion. Das Faden des main Funktion wird dadurch beendet. Es scheint, dass Sie verwirrend sind main Funktion, ihren Ausführungsfaden und den Prozess, der sich neu gruppiert alle Fäden. Das main Funktion ist in zweierlei Hinsicht besonders: es ist die Erste Thread des Prozesses, der beginnt, und wenn er beendet wird return oder exit es beendet den gesamten Prozess. Aber wenn du es beendest pthread_exitnur dass Thread endet und die anderen bleiben.

    – Jens Gustedt

    29. Dezember 2013 um 14:35 Uhr

Benutzeravatar von MichaelGoren
Michael Goren

Die pthread_exit()-API

wird, wie bereits erwähnt, für die Beendigung des aufrufenden Threads verwendet. Nach einem Aufruf dieser Funktion wird ein komplizierter Aufräummechanismus gestartet. Wenn es fertig ist, wird der Thread beendet. Die pthread_exit()-API wird auch implizit aufgerufen, wenn ein Aufruf der return()-Routine in einem von pthread_create() erstellten Thread auftritt. Tatsächlich haben ein Aufruf von return() und ein Aufruf von pthread_exit() dieselbe Auswirkung, da sie von einem Thread aufgerufen werden, der von pthread_create() erstellt wurde.

Es ist sehr wichtig, den anfänglichen Thread, der implizit beim Start der main()-Funktion erstellt wird, und Threads zu unterscheiden, die von pthread_create() erstellt werden. Ein Aufruf der Routine return() von der Funktion main() ruft implizit den Systemaufruf exit() auf und der gesamte Prozess wird beendet. Es wird kein Thread-Bereinigungsmechanismus gestartet. Ein Aufruf von pthread_exit() von der main()-Funktion bewirkt, dass der Aufräummechanismus startet und wenn er seine Arbeit beendet, wird der anfängliche Thread beendet.

Was mit dem gesamten Prozess (und anderen Threads) passiert, wenn pthread_exit() von der main()-Funktion aufgerufen wird, hängt von der PTHREAD-Implementierung ab. Beispielsweise wird bei einer IBM OS/400-Implementierung der gesamte Prozess beendet, einschließlich anderer Threads, wenn pthread_exit() von der main()-Funktion aufgerufen wird. Andere Systeme können sich anders verhalten. Auf den meisten modernen Linux-Rechnern beendet ein Aufruf von pthread_exit() vom Anfangs-Thread nicht den gesamten Prozess, bis alle Threads beendet sind.
Seien Sie vorsichtig bei der Verwendung von pthread_exit() von main(), wenn Sie eine portable Anwendung schreiben möchten.

Die pthread_join()-API

ist eine bequeme Möglichkeit, auf eine Thread-Beendigung zu warten. Sie können Ihre eigene Funktion schreiben, die auf eine Thread-Beendigung wartet, vielleicht besser geeignet für Ihre Anwendung, anstatt pthread_join() zu verwenden. Beispielsweise kann es sich um eine Funktion handeln, die auf dem Warten auf bedingte Variablen basiert.

Ich würde zum Lesen ein Buch empfehlen David R. Butenhof „Programmieren mit POSIX-Threads“.
Es erklärt die besprochenen Themen (und kompliziertere Dinge) sehr gut (obwohl einige Implementierungsdetails, wie die Verwendung von pthread_exit in der Hauptfunktion, nicht immer im Buch widergespiegelt werden).

Benutzeravatar von Basile Starynkevitch
Basile Starynkevitch

Sie brauchen keine Anrufe zu pthread_exit(3) in Ihrem speziellen Code.

Im Allgemeinen ist die main Faden sollte nicht Anruf pthread_exitsollte aber oft anrufen pthread_join(3) zu Warten um einen anderen Thread zu beenden.

In deiner PrintHello Funktion, Sie müssen nicht anrufen pthread_exit weil es nach der Rückkehr von ihm implizit ist.

Ihr Code sollte also eher sein:

void *PrintHello(void *threadid)  {
  long tid = (long)threadid;
  printf("Hello World! It's me, thread #%ld!\n", tid);
  return threadid;
}

int main (int argc, char *argv[]) {
   pthread_t threads[NUM_THREADS];
   int rc;
   intptr_t t;
   // create all the threads
   for(t=0; t<NUM_THREADS; t++){
     printf("In main: creating thread %ld\n", (long) t);
     rc = pthread_create(&threads
     if (rc) { fprintf(stderr, "failed to create thread #%ld - %s\n",
                                (long)t, strerror(rc));
               exit(EXIT_FAILURE);
             };
   }
   pthread_yield(); // useful to give other threads more chance to run
   // join all the threads
   for(t=0; t<NUM_THREADS; t++){
      printf("In main: joining thread #%ld\n", (long) t);
      rc = pthread_join(&threads
      if (rc) { fprintf(stderr, "failed to join thread #%ld - %s\n",
                                (long)t, strerror(rc));
               exit(EXIT_FAILURE);
      }
   }
}

pthread_exit() beendet den aufrufenden Thread und verlässt diesen (aber die vom aufrufenden Thread verwendeten Ressourcen werden nicht für das Betriebssystem freigegeben, wenn sie nicht vom Hauptthread getrennt sind.)

pthrade_join() wartet oder blockiert den aufrufenden Thread, bis der Ziel-Thread nicht beendet wird. In einfachen Worten, es wird darauf gewartet, den Ziel-Thread zu verlassen.

In Ihrem Code, wenn Sie sleep (oder delay) eingeben PrintHello Funktion vor pthread_exit()dann kann der Hauptthread beendet werden und den vollständigen Prozess beenden, obwohl Ihr PrintHello Funktion nicht abgeschlossen ist, wird sie beendet. Wenn du benutzt pthrade_join() Funktion in main vor dem Aufruf pthread_exit() von main blockiert es den Haupt-Thread und wartet, bis der aufrufende Thread abgeschlossen ist (PrintHello).

Benutzeravatar von jim mcnamara
Jim Mcnamara

Hmm.

POSIX pthread_exit Beschreibung ab http://pubs.opengroup.org/onlinepubs/009604599/functions/pthread_exit.html:

After a thread has terminated, the result of access to local (auto) variables of the thread is 
undefined. Thus, references to local variables of the exiting thread should not be used for 
the pthread_exit() value_ptr parameter value.

Was der Idee zu widersprechen scheint, dass lokale main()-Thread-Variablen zugänglich bleiben.

1412260cookie-checkWann sollte pthread_exit() und wann pthread_join() unter Linux verwendet werden?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy