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