valgrindでpthread_をデバッグするcreateによるメモリ漏洩------ついでにスレッドのjoinableとdetached属性を熟知する


valgrindのインストールとデバッグは簡単で、前にブログで何度も紹介しました(ubuntuであれば、直接aptのインストールはもっと簡単で、1つのコマンドで終わります).最近、メモリの漏洩の問題が解決しにくい問題に遭遇しました.次に、コアロジックを抽出します.簡単に言えば、次のようにします.
まずこのプログラムを見てみましょう.
#include 
#include 
#include 
#include 

void* threadFunc(void* p)  
{  
	char szTest[1024 * 32] = {0};
    return NULL;  
}  
 
int main(void)
{
	pthread_t id;  
    pthread_create (&id, NULL, threadFunc, NULL);  
	
	sleep(1);
    return 0;
}

コンパイル実行:
ubuntu@VM-0-15-ubuntu:~/taoge/cpp$ g++ -g test.cpp -lpthread      
ubuntu@VM-0-15-ubuntu:~/taoge/cpp$ valgrind --tool=memcheck --leak-check=yes --show-reachable=yes ./a.out  
==22531== Memcheck, a memory error detector
==22531== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==22531== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==22531== Command: ./a.out
==22531== 
==22531== 
==22531== HEAP SUMMARY:
==22531==     in use at exit: 272 bytes in 1 blocks
==22531==   total heap usage: 1 allocs, 0 frees, 272 bytes allocated
==22531== 
==22531== 272 bytes in 1 blocks are possibly lost in loss record 1 of 1
==22531==    at 0x4C2FB55: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==22531==    by 0x40138A4: allocate_dtv (dl-tls.c:322)
==22531==    by 0x40138A4: _dl_allocate_tls (dl-tls.c:539)
==22531==    by 0x4E4226E: allocate_stack (allocatestack.c:588)
==22531==    by 0x4E4226E: pthread_create@@GLIBC_2.2.5 (pthread_create.c:539)
==22531==    by 0x40077C: main (test.cpp:15)
==22531== 
==22531== LEAK SUMMARY:
==22531==    definitely lost: 0 bytes in 0 blocks
==22531==    indirectly lost: 0 bytes in 0 blocks
==22531==      possibly lost: 272 bytes in 1 blocks
==22531==    still reachable: 0 bytes in 0 blocks
==22531==         suppressed: 0 bytes in 0 blocks
==22531== 
==22531== For counts of detected and suppressed errors, rerun with: -v
==22531== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
ubuntu@VM-0-15-ubuntu:~/taoge/cpp$ 

メモリリーク(possibly lost)がありますが、なぜですか?スレッドのデフォルトはjoinableなので、終了するときはpthread_が必要ですjoinはリソースを回収します.
#include 
#include 
#include 
#include 

void* threadFunc(void* p)  
{  
	char szTest[1024 * 32] = {0};
    return NULL;  
}  
 
int main(void)
{
	void *ret;
	
	pthread_t id;  
    pthread_create (&id, NULL, threadFunc, NULL);  
	
	pthread_join(id, &ret);
	
	sleep(1);
    return 0;
}

コンパイル実行:
ubuntu@VM-0-15-ubuntu:~/taoge/cpp$ g++ -g test.cpp -lpthread                      ubuntu@VM-0-15-ubuntu:~/taoge/cpp$ 
ubuntu@VM-0-15-ubuntu:~/taoge/cpp$ valgrind --tool=memcheck --leak-check=yes --show-reachable=yes ./a.out  
==22710== Memcheck, a memory error detector
==22710== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==22710== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==22710== Command: ./a.out
==22710== 
==22710== 
==22710== HEAP SUMMARY:
==22710==     in use at exit: 0 bytes in 0 blocks
==22710==   total heap usage: 1 allocs, 1 frees, 272 bytes allocated
==22710== 
==22710== All heap blocks were freed -- no leaks are possible
==22710== 
==22710== For counts of detected and suppressed errors, rerun with: -v
==22710== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
ubuntu@VM-0-15-ubuntu:~/taoge/cpp$ 

メモリの漏洩がないことがわかります.
デフォルトのjoinableからdetachedにスレッドを変更する考え方もあります.これにより、スレッドは終了時に自分でリソースを解放します.
#include 
#include 
#include 
#include 

void* threadFunc(void* p)  
{  
	char szTest[1024 * 32] = {0};
    return NULL;  
}  
 
int main(void)
{
	size_t ui_stack_size = 0;
	pthread_attr_t attr;
	
	pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

	pthread_t id;  
    pthread_create (&id, &attr, threadFunc, NULL);  
	
	pthread_attr_destroy(&attr);
	
	sleep(1);
	
    return 0;
}
コンパイル実行:
ubuntu@VM-0-15-ubuntu:~/taoge/cpp$ g++ -g test.cpp -lpthread                      ubuntu@VM-0-15-ubuntu:~/taoge/cpp$ 
ubuntu@VM-0-15-ubuntu:~/taoge/cpp$ valgrind --tool=memcheck --leak-check=yes --show-reachable=yes ./a.out  
==22900== Memcheck, a memory error detector
==22900== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==22900== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==22900== Command: ./a.out
==22900== 
==22900== 
==22900== HEAP SUMMARY:
==22900==     in use at exit: 0 bytes in 0 blocks
==22900==   total heap usage: 1 allocs, 1 frees, 272 bytes allocated
==22900== 
==22900== All heap blocks were freed -- no leaks are possible
==22900== 
==22900== For counts of detected and suppressed errors, rerun with: -v
==22900== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
ubuntu@VM-0-15-ubuntu:~/taoge/cpp$ 

メモリが漏れていません.
二つの方法は、それぞれ千秋があり、具体的な状況に応じて選択すればいい.