GNU/Linux >> Tutoriels Linux >  >> Linux

pthread_exit vs retour

Je ne sais pas si cela vous intéresse toujours, mais je suis actuellement en train de déboguer une situation similaire. Threads utilisant pthread_exit oblige valgrind à signaler les blocs accessibles. La raison semble être assez bien expliquée ici :

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

Essentiellement, il semble pthread_exit provoque un dlopen qui n'est jamais nettoyé explicitement lorsque le processus se termine.


Le cas de test minimal suivant présente le comportement que vous décrivez :

#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 montre 5 blocs alloués à partir de fonctions appelées par pthread_exit() qui n'est pas libéré mais toujours accessible à la sortie du processus. Si le pthread_exit(0); est remplacé par return 0; , les 5 blocs ne sont pas alloués.

Cependant, si vous testez la création et la jonction d'un grand nombre de threads, vous constaterez que la quantité de mémoire non libérée utilisée à la sortie ne le fait pas augmenter. Ceci, et le fait qu'il soit toujours accessible, indique que vous ne voyez qu'une bizarrerie de l'implémentation de la glibc. Plusieurs fonctions de la glibc allouent de la mémoire avec malloc() la première fois qu'ils sont appelés, qu'ils gardent alloués pour le reste de la durée de vie du processus. La glibc ne prend pas la peine de libérer cette mémoire à la sortie du processus, car elle sait que le processus est de toute façon détruit - ce serait juste une perte de cycles CPU.


Utilisez-vous réellement C++, par hasard? Pour clarifier - votre fichier source se termine par un .c extension, et vous la compilez avec gcc , pas g++ ?

Il semble raisonnablement probable que votre fonction alloue des ressources que vous vous attendez à nettoyer automatiquement lors du retour de la fonction. Objets C++ locaux comme std::vector ou std::string faites ceci, et leurs destructeurs ne seront probablement pas exécutés si vous appelez pthread_exit , mais serait nettoyé si vous venez de revenir.

Ma préférence est d'éviter les API de bas niveau telles que pthread_exit , et revenez toujours de la fonction thread, si possible. Ils sont équivalents, sauf que pthread_exit est une construction de contrôle de flux de facto qui contourne le langage que vous utilisez, mais return pas.


Linux
  1. Processus de démarrage Linux

  2. Qu'est-ce qu'un processus ininterrompu ?

  3. Comment obtenir la valeur de retour de CHILD PROCESS ?

  4. Que retourne malloc(0) ?

  5. return() contre pthread_exit() dans les fonctions de démarrage de pthread

Comment tuer un processus sous Linux

Commande Pstree sous Linux

Commande Kill sous Linux

Surveillance des processus sous Linux

Descendants de processus ?

États de processus Linux