Detached vs. Joinable POSIX-Threads

Lesezeit: 5 Minuten

Ich benutze die pthread Bibliothek zum Erstellen und Verbinden von Threads in C.

  1. Wann sollte ich einen Thread von Anfang an als losgelöst anlegen? Bietet es einen Leistungsvorteil gegenüber einem verbindbaren Thread?

  2. Ist es legal, a pthread_join() in einem beitretbaren (standardmäßig) Thread? Oder sollte man so einen Thread immer benutzen detach() Funktion vor pthread_exit()ing?

  1. Erstellen Sie einen getrennten Thread, wenn Sie wissen, dass Sie nicht darauf warten möchten pthread_join(). Der einzige Leistungsvorteil besteht darin, dass beim Beenden eines getrennten Threads seine Ressourcen sofort freigegeben werden können, anstatt auf den Beitritt des Threads warten zu müssen, bevor die Ressourcen freigegeben werden können.

  2. Es ist ‘legal’, einem beitretbaren Thread nicht beizutreten; aber es ist normalerweise nicht ratsam, weil (wie bereits erwähnt) die Ressourcen nicht freigegeben werden, bis der Thread beigetreten ist, so dass sie auf unbestimmte Zeit gebunden bleiben (bis das Programm beendet wird), wenn Sie ihm nicht beitreten.

  • Zweifel: Was ist, wenn bei getrennten Threads die Ausführung des Haupt-Threads beendet wird, bevor der getrennte Thread beendet ist? Ich denke, dies würde den Prozess beenden und alle Threads töten. In welchen Szenarien werden getrennte Threads verwendet, weil ich sicher sein sollte, dass der getrennte Thread die Ausführung beendet hat?

    – Ajax

    18. November 2014 um 6:28 Uhr


  • @Ajax: Empirisch, wenn der Haupt-Thread beendet wird, wird das Programm beendet und die Threads werden … beendet. Das scheint zumindest das Verhalten von Mac OS X (10.10.1 Yosemite) zu sein. Ich kann in der POSIX-Dokumentation nichts finden, was darauf hinweist, dass andere Threads fortgesetzt werden, wenn exit() oder _exit() oder _Exit() wird genannt. Wenn der Hauptthread das tut pthread_exit()dann haben die anderen Threads die Möglichkeit, abgeschlossen zu werden.

    – Jonathan Leffler

    18. November 2014 um 7:12 Uhr


  • Auf einer anderen Anmerkung: Trennbare Threads sind gut, wenn Sie bereits einen anderen Polling-Mechanismus haben; Sie können denselben Polling-Mechanismus verwenden, um den Ergebnisstatus zu überprüfen und so zu wissen, ob der Thread abgeschlossen ist oder nicht. Es ist ein Fall von “Ist es fertig? Wenn ja, benutze es.”

    – Techniker

    19. Februar 2015 um 13:11 Uhr

  • Kann ich pthread_detach aufrufen, bevor es beendet wird, um Speicherverluste zu vermeiden, wenn ich vergesse, pthread_join aufzurufen?

    – Antonio Petricca

    31. März 2016 um 13:11 Uhr

  • @DareDevil: Ja, aber…. Sie sollten den Thread trennen, weil Sie den Rückgabestatus des Threads nicht kennen müssen und Sie nicht wissen müssen, dass er beendet ist, und nicht, weil Sie möglicherweise vergessen, ihm beizutreten. Und sobald Sie sich gelöst haben, dürfen Sie nicht versuchen, sich dem Thread anzuschließen.

    – Jonathan Leffler

    31. März 2016 um 13:50 Uhr

Wann sollte ich einen Thread von Anfang an als losgelöst anlegen?

Immer wenn es der Anwendung egal ist, wann dieser Thread abgeschlossen ist, und sich auch nicht um den Rückgabewert eines Threads kümmert (ein Thread kann einen Wert an einen anderen Thread/eine andere Anwendung über pthread_exit).

Beispielsweise kann in einem Client-Server-Anwendungsmodell ein Server einen neuen Thread erstellen, um jede Anforderung zu verarbeiten. Aber der Server selbst kümmert sich nicht um den Rückgabewert des Threads. In diesem Fall ist es sinnvoll, zu erstellen losgelöst Fäden.

Der Server muss lediglich sicherstellen, dass die aktuell verarbeiteten Anfragen abgeschlossen werden. Was es tun kann, indem es einfach den Hauptthread beendet, ohne das gesamte Programm/die gesamte Anwendung zu beenden. Wenn der letzte Thread im Prozess beendet wird, wird die Anwendung/das Programm natürlich beendet.

Der Pseudocode könnte wie folgt aussehen:

/* A server application */

void process(void *arg)
{
    /* Detach self. */
    pthread_detach(pthread_self());
    
    /* process a client request. */
    
    pthread_exit(NULL);
}

int main(void)
{

    while (not_done) {
        pthread_t t_id;
        errno = pthread_create(&t_id, NULL, process, NULL);
        if (errno) perror("pthread_create:");
    }

    /* There may be pending requests at this point. */
    
    /* Just exit the main thread - not the whole program - so that remaining
       requests that may still be processed can continue. */
    pthread_exit(NULL);
}

Ein weiteres Beispiel könnte ein Daemon oder Logger-Thread sein, der einige Informationen in regelmäßigen Abständen protokolliert, solange die Anwendung läuft.

Bietet es einen Leistungsvorteil gegenüber einem verbindbaren Thread?

Leistungsmäßig gibt es keinen Unterschied zwischen vereinbar Fäden vs losgelöst Fäden. Der einzige Unterschied besteht darin, dass bei getrennten Threads deren Ressourcen (z. B. Thread-Stack und zugehöriger Heap-Speicher usw.) implementierungsspezifisch sind.

Ist es legal, kein pthread_join() für einen verknüpfbaren (standardmäßig) Thread auszuführen?

Ja, es ist legal, einem Thread nicht beizutreten. pthread_join ist eine einfache Komfortfunktion, die auf keinen Fall verwendet werden muss, es sei denn, Sie brauchen es. Aber beachten Sie, dass die Threads erstellt werden vereinbar Threads standardmäßig.

Ein Beispiel, wenn Sie beitreten möchten, ist, wenn Threads ein „Stück“ Arbeit erledigen, das zwischen ihnen aufgeteilt wird. In diesem Fall sollten Sie alle Threads auf Vollständigkeit überprüfen, bevor Sie fortfahren. Task-Farm-Parallelität ist ein gutes Beispiel.

Oder sollte ein solcher Thread vor dem pthread_exit()ing immer die disconnect()-Funktion verwenden?

Nicht nötig. Aber Sie möchten oft entscheiden, ob Sie eine möchten vereinbar oder losgelöst Thread zum Zeitpunkt der Erstellung.


Beachten Sie, dass zwar ein trennbarer Thread erstellt werden kann, indem Sie das Attribut festlegen PTHREAD_CREATE_DETACHED mit einem Anruf bei pthread_attr_setdetachstateein Thread kann sich jederzeit zB mit entscheiden, sich abzumelden pthread_detach(pthread_self()). Auch ein Thread mit der Thread-ID (pthread_t) eines anderen Threads kann sich mit lösen pthread_detach(thread_id);.

  • Was ist der Unterschied zwischen “Beenden des Hauptthreads” und “Beenden des gesamten Programms/der gesamten Anwendung”?

    – Yd Ahhrk

    10. Juni 2021 um 20:12 Uhr

  • @ YdAhhrk Aufruf pthread_exit aus dem Hauptthread beendet nur diesen Thread und der Prozess wird weiter ausgeführt, wenn andere Threads ausgeführt werden. Das meine ich mit “den Hauptthread verlassen”. OTOH, rufend exit von jedem Thread beendet beispielsweise den gesamten Prozess/die gesamte Anwendung.

    – PP

    12. Juni 2021 um 9:06 Uhr

1414820cookie-checkDetached vs. Joinable POSIX-Threads

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

Privacy policy