我最近一直在尝试线程本地存储。我有工作代码,每件事似乎都很好但是当我用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
答案 0 :(得分:4)
线程退出时不会自动删除。您已在线程本地存储中声明了一个指针。运行时框架不知道你打算如何使用该对象,因此它不能假设内存是动态分配的。
您需要自己释放内存。
答案 1 :(得分:0)
是的,你应该在pthread_exit之前释放。 pthread_exit不会自动释放。
free(string);
应该这样做。
答案 2 :(得分:0)
删除了线程局部变量,但是对于任何指针变量,它指向的对象都不会自动释放:C没有像析构函数的C ++概念那样。
__thread
是gcc的扩展,但它对应于新C11标准的新功能_Threadlocal
。
如果您使用POSIX进行多线程处理,那么在“keys”上运行的类似名称pthread_getspecific
可以让您设计线程本地对象。它的优点是它具有析构函数的概念,您可以将其与“键”/