1

私は簡単なスレッドプログラムを書きました:

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdint.h>

#define THREADS     5

void* HelloWorld(void *t) 
{
    printf("Thread ID #%lu: (%lu) Hello World !!\n", pthread_self(), (unsigned long)t);         

    return NULL;
}

int main()
{
    pthread_t thread[THREADS];
    uint32_t i;
    int err;

    for(i = 0; i < THREADS; ++i)
    {   
        err = pthread_create(&thread[i], NULL, &HelloWorld, (void*)(unsigned long long)i);
        if(err != 0)
        {   
            printf("Error %d: Thread %d Creation Unsuccessful !!\n", err, i); 
        }   
        printf("Thread %lu in main()\n", pthread_self());
    }   
/*
    for(i = 0; i < THREADS; ++i)
    {
        pthread_join(thread[i], NULL);  // Error checking implemented
    }
*/
    return 0;
}

ただし、valgrindを次のように使用する場合:

valgrind --tool=memcheck --leak-check=full --show-reachable=yes ./hello

pthread_join()プログラムで使用されているかどうかに関係なく、メモリ使用量/リークについて同じ出力が表示されます。

ここで読んだように、この動作を説明してください:

pthread_join() または pthread_detach() 関数は、スレッドに関連付けられたストレージを再利用できるように、detachstate 属性を PTHREAD_CREATE_JOINABLE に設定して作成されたすべてのスレッドに対して最終的に呼び出す必要があります。

呼び出さない場合のストレージの再利用方法pthread_join()

4

1 に答える 1

1

私が理解していることから提起された2つの質問があります。1 つは、valgrindへの呼び出しの有無にかかわらず、同じメモリ リークがレポートされる理由です。pthread_join()pthread_join()

両方の問題の考えられる説明の 1 つは、スレッド ライブラリが の呼び出し後にメモリを実際に解放せず、pthread_join()割り当てられたリソースを「将来別のスレッドを作成することになった場合に使用できる」コンテナに配置することです。そのコンテナをプールと呼びましょう。への次の呼び出しpthread_create()では、プール内にあるすべてのリソースを再利用できます。プールが空の場合、新しいメモリが割り当てられます。

を呼び出さないpthread_join()と、終了したスレッドに関連付けられているリソースはプールに返されません。したがって、これらのリソースは使用できないままになり、プールは空のままになるため、新しいpthread_create()スレッド作成要求により多くのリソースが割り当てられます。

これは、 apthread_join()がメモリをまったく解放するとは限らないことを意味します。取得したリソースを、スレッド ライブラリによって維持されるプールに単純に配置することもできます。したがって、 へpthread_join()の呼び出しの有無にかかわらず、valgrind同じ量の「リークした」メモリが表示されます。ただし、メモリはpthread_join()、将来の への呼び出しのためにプールに配置されるため、によって再利用されpthread_create()ます。

于 2013-08-26T06:04:59.753 に答える