GNU/Linux >> LINUX-Kenntnisse >  >> Linux

pthread_exit vs. return

Ich bin mir nicht sicher, ob Sie noch daran interessiert sind, aber ich debugge derzeit eine ähnliche Situation. Threads, die pthread_exit verwenden Valgrind veranlassen, erreichbare Blöcke zu melden. Der Grund scheint hier ziemlich gut erklärt zu sein:

https://bugzilla.redhat.com/show_bug.cgi?id=483821

Im Wesentlichen scheint es pthread_exit zu sein verursacht einen dlopen die niemals explizit bereinigt wird, wenn der Prozess beendet wird.


Der folgende minimale Testfall zeigt das von Ihnen beschriebene Verhalten:

#include <pthread.h>
#include <unistd.h>

void *app1(void *x)
{
    sleep(1);
    pthread_exit(0);
}

int main()
{
    pthread_t t1;

    pthread_create(&t1, NULL, app1, NULL);
    pthread_join(t1, NULL);

    return 0;
}

valgrind --leak-check=full --show-reachable=yes zeigt 5 Blöcke, die von Funktionen zugewiesen wurden, die von pthread_exit() aufgerufen wurden das ist nicht freigegeben, aber am Prozessende noch erreichbar. Wenn der pthread_exit(0); wird durch return 0; ersetzt , die 5 Blöcke sind nicht belegt.

Wenn Sie jedoch das Erstellen und Verbinden einer großen Anzahl von Threads testen, werden Sie feststellen, dass die Menge an nicht freigegebenem Speicher, die beim Beenden verwendet wird, nicht ist Zunahme. Dies und die Tatsache, dass es immer noch erreichbar ist, weist darauf hin, dass Sie nur eine Kuriosität der glibc-Implementierung sehen. Mehrere glibc-Funktionen weisen Speicher mit malloc() zu das erste Mal, wenn sie aufgerufen werden, die ihnen für den Rest der Prozesslebensdauer zugewiesen bleiben. glibc macht sich nicht die Mühe, diesen Speicher beim Beenden des Prozesses freizugeben, da es weiß, dass der Prozess ohnehin abgebaut wird - es wäre nur eine Verschwendung von CPU-Zyklen.


Benutzt du zufällig C++? Zur Verdeutlichung - Ihre Quelldatei endet mit einem .c Erweiterung, und Sie kompilieren sie mit gcc , nicht g++ ?

Es scheint ziemlich wahrscheinlich, dass Ihre Funktion Ressourcen zuweist, von denen Sie erwarten, dass sie automatisch bereinigt werden, wenn die Funktion zurückkehrt. Lokale C++-Objekte wie std::vector oder std::string Wenn Sie dies tun, werden ihre Destruktoren wahrscheinlich nicht ausgeführt, wenn Sie pthread_exit aufrufen , würde aber aufgeräumt werden, wenn Sie einfach zurückkehren.

Ich bevorzuge es, Low-Level-APIs wie pthread_exit zu vermeiden , und kehren Sie nach Möglichkeit immer nur von der Thread-Funktion zurück. Sie sind äquivalent, außer dass pthread_exit ist ein De-facto-Flusssteuerungskonstrukt, das die von Ihnen verwendete Sprache umgeht, aber return nicht.


Linux
  1. Warum ist Cd kein Programm?

  2. Linux-Prozesszustände

  3. Linux-CreateProcess?

  4. Welchen Fehlercode gibt ein Prozess zurück, der Segfaults zurückgibt?

  5. Erstellen eines Daemons unter Linux

So beenden Sie einen Prozess in Linux

Pstree-Befehl unter Linux

Kill-Befehl unter Linux

Prozessüberwachung unter Linux

Was gibt malloc(0) zurück?

return() versus pthread_exit() in pthread-Startfunktionen