7

最近、スレッド ローカル ストレージを試しています。動作するコードがあり、すべて問題ないように見えますが、valgrind でプログラムを実行すると、いくつかの問題があるように見えます。

私の質問は、メモリを静的スレッド ローカル ストレージに割り当てた場合、スレッドの終了時に削除されますか?

これが私のコードです:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <pthread.h>


void *test (void *arg) 
{
    static __thread int val = 0;
    static __thread char *string = NULL;

    string = (char *) calloc (100, sizeof (char));

    strcpy (string, "hello");

    val++;

    printf ("val(%p):%d\n", &val, val);
    printf ("string(%p):%s\n", &string, string);

    pthread_exit (NULL);
}


int main (int argc, char *argv[])
{
    int num_threads = 10, i;
    pthread_t tid[num_threads];

    for (i=0;i<num_threads;i++) {
        pthread_create (&tid[i], NULL, &test, NULL);
    }

    for (i=0;i<num_threads;i++) {
        pthread_join (tid[i], NULL);
    }

    return 0;
}

出力:

val(0x7122b8c):1
string(0x7122b88):hello
val(0x7b23b8c):1
string(0x7b23b88):hello
val(0x924ab8c):1
string(0x924ab88):hello
val(0x9c4bb8c):1
string(0x9c4bb88):hello
val(0xa64cb8c):1
string(0xa64cb88):hello
val(0xb04db8c):1
string(0xb04db88):hello
val(0xba4eb8c):1
string(0xba4eb88):hello
val(0xc44fb8c):1
string(0xc44fb88):hello
val(0xce50b8c):1
string(0xce50b88):hello
val(0xd851b8c):1
string(0xd851b88):hello

valgrind:

==9366== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 41 from 1)
==9366== malloc/free: in use at exit: 1,916 bytes in 15 blocks.
==9366== malloc/free: 70 allocs, 55 frees, 11,218 bytes allocated.
==9366== For counts of detected errors, rerun with: -v
==9366== searching for pointers to 15 not-freed blocks.
==9366== checked 335,336 bytes.
==9366== 
==9366== 1,000 bytes in 10 blocks are definitely lost in loss record 6 of 6
==9366==    at 0x43BB6FF: calloc (vg_replace_malloc.c:279)
==9366==    by 0x80485CD: test (pthread_test.c:14)
==9366==    by 0x51C73A: start_thread (in /lib/libpthread-2.5.so)
==9366==    by 0x4A0CFD: clone (in /lib/libc-2.5.so)
==9366== 
==9366== LEAK SUMMARY:
==9366==    definitely lost: 1,000 bytes in 10 blocks.
==9366==      possibly lost: 0 bytes in 0 blocks.
==9366==    still reachable: 916 bytes in 5 blocks.
==9366==         suppressed: 0 bytes in 0 blocks.
==9366== Reachable blocks (those to which a pointer was found) are not shown.
==9366== To see them, rerun with: --show-reachable=yes
4

3 に答える 3

0

スレッド ローカル変数は削除されますが、ポインター変数に関しては、それが指すオブジェクトは自動的に割り当て解除されません。C には、C++ のデストラクタの概念のようなものはありません。

__threadは gcc による拡張機能です_Threadlocalが、新しい C11 標準の新しい機能 に対応しています。

pthread_getspecificマルチスレッド用に POSIX を使用している場合、スレッド ローカル オブジェクトを設計できる「キー」の操作と呼ばれる同様のものがあります。これには、「キー」に関連付けることができるデストラクタ関数の概念があるという利点があります/

于 2013-11-06T21:33:18.967 に答える