pthread_createしたらjoinを忘れない
概要
pthread_createで作ったスレッドはdetachしない限りはjoinしないとスタックなどのリソースが 解放されない。従ってjoinするのを忘れるとメモリリークを起こす。pthread_createでスレッドを作ったらdetachするか必ずjoinすること
ソースと実行結果
はじめにjoinを使用した場合の仮想メモリの状態をみる。この場合のソースは次の通り
pthread.c
コンパイルの方法は gcc -o pthread -pthread pthread.c
#include <stdio.h> #include <sys/types.h> #include <stdlib.h> #include <pthread.h> void* thread_main( void* args ) { fprintf( stderr, "start thread\n" ); fprintf( stderr, "end thread\n" ); return NULL; } int main() { int i; char command[256]; sprintf( command, "grep VmSize /proc/%d/status", getpid() ); fprintf( stderr, "実行前\n" ); system( command ); for( i=0; i<3; ++i ){ fprintf( stderr, "実行\n" ); pthread_t thread; pthread_create( &thread, NULL, thread_main, (void *)NULL ); pthread_join( thread, NULL ); system( command ); } fprintf( stderr, "end mainthread\n" ); return 0; }
実行結果は
実行前 VmSize: 1556 kB 実行 start thread end thread VmSize: 11932 kB 実行 start thread end thread VmSize: 11932 kB 実行 start thread end thread VmSize: 11932 kB end mainthread
よって仮想メモリがきちんと解放されていることが分かる。 一方、
pthread_join( thread, NULL );を
sleep( 2 )に変更してjoinしなかった場合の結果は
実行前 VmSize: 2380 kB 実行 start thread end thread VmSize: 12756 kB 実行 start thread end thread VmSize: 23000 kB 実行 start thread end thread VmSize: 33244 kB end mainthreadとなり仮想メモリが解放されずメモリリークが生じていることが分かる。また
pthread_detach( thread ); sleep( 2 );とスレッドをdetachした場合の結果は
実行前 VmSize: 1744 kB 実行 start thread end thread VmSize: 12120 kB 実行 start thread end thread VmSize: 12120 kB 実行 start thread end thread VmSize: 12120 kB end mainthreadとなり仮想メモリが解放されていることが分かる。