Un pthread détaché provoque des memory leaks

Il existe une fuite de mémoire connue lorsque vous terminez un processus avec l’exécution de pthreads non détachés. Cependant, le détachement du thread ne semble pas être une solution. Prenons l’exemple minimal suivant:

#include  #include  static void* thread(void* _) { for(;;); return NULL; } int main(void) { pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_t tid; pthread_create(&tid, &attr, thread, NULL); pthread_attr_destroy(&attr); return 0; } 

Un thread détaché avec une boucle infinie est créé et le processus est immédiatement terminé. Selon pthread_detach(3) , les ressources du thread doivent être automatiquement relâchées sur le système une fois le processus terminé. Ce n’est cependant pas ce qui se passe:

 gcc -pthread cc valgrind --leak-check=full a.out ==9341== Command: a.out ==9341== ==9341== ==9341== HEAP SUMMARY: ==9341== in use at exit: 272 bytes in 1 blocks ==9341== total heap usage: 1 allocs, 0 frees, 272 bytes allocated ==9341== ==9341== 272 bytes in 1 blocks are possibly lost in loss record 1 of 1 ==9341== at 0x4C2ABB4: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==9341== by 0x4012598: _dl_allocate_tls (dl-tls.c:296) ==9341== by 0x4E3C7B5: pthread_create@@GLIBC_2.2.5 (allocatestack.c:579) ==9341== by 0x400825: main (in /home/witiko/a.out) ==9341== ==9341== LEAK SUMMARY: ==9341== definitely lost: 0 bytes in 0 blocks ==9341== indirectly lost: 0 bytes in 0 blocks ==9341== possibly lost: 272 bytes in 1 blocks ==9341== still reachable: 0 bytes in 0 blocks ==9341== suppressed: 0 bytes in 0 blocks 

Devrais-je m’inquiéter? Dans le programme actuel, j’ai plusieurs threads bloquants, donc, comme dans l’exemple minimal, je ne peux pas vraiment pthread_join() avec eux. Dois-je appeler pthread_cancel() au lieu de exit() directement?

Revenir de main est équivalent à une exit de l’ensemble du processus, donc c’est une manière assez grossière de terminer votre thread détaché. Votre thread ne s’est tout simplement pas arrêté lorsque la fonction main se termine, il ne le fait plus tard que lorsque le mécanisme de exit force. Donc, valgrind manque la libération des ressources du thread.

Le fait que valgrind vous dise qu’il y a une fuite de mémoire ne devrait pas vous inquiéter vous-même, mais le fait que votre thread soit terminé sans pouvoir nettoyer et / ou terminer sa tâche devrait vous inquiéter.

Si vous voulez que votre thread continue son exécution après la fin de votre thread main , vous devez terminer par main par pthread_exit au lieu de return . Ensuite, c’est à votre fil détaché de décider quand se terminer. Il pourrait en être ainsi, en recevant les informations nécessaires à travers une variable d’état qui est définie de manière atomique ou via un mécanisme de mutex / condition.