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となり仮想メモリが解放されていることが分かる。