我编写了一个程序来了解Linux上的线程特定数据(Linux 3.13.0-24-generic #46-Ubuntu),如下所示。
我试图在传递给pthread_key_create()的析构函数中打印线程id,但似乎只有子线程成功打印,但是主线程没有打印该信息。
我的问题是:
析构函数是在线程终止之前还是之后调用的?
为什么主线程没有打印信息,是因为主线程已经被破坏了吗?
tsd_test.c
// test of thread-specific data
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <errno.h>
static pthread_once_t once = PTHREAD_ONCE_INIT;
static pthread_key_t tidKey;
static void destructor(void *buf) {
unsigned long *_tid = buf;
printf("destroy, tid: %lu\n", *_tid);
free(buf);
}
static void createKey(void) {
int s = pthread_key_create(&tidKey, destructor);
if(s != 0) {
printf("failed to create key\n");
exit(-1);
}
}
void *store_tid() {
int s;
unsigned long *buf;
// create key
s = pthread_once(&once, createKey);
if(s != 0) {
printf("failed to create key\n");
exit(-1);
}
buf = pthread_getspecific(tidKey);
if(buf == NULL) { // thread call this function for the first time,
buf = malloc(sizeof(unsigned long));
if(buf == NULL) {
printf("failed to allocate memory, %s\n", strerror(errno));
exit(-1);
}
// register buffer to specified key & current thread,
s = pthread_setspecific(tidKey, buf);
if(s != 0) {
printf("failed to setspecific\n");
exit(-1);
}
}
// store tid to buffer,
*buf = (unsigned long)pthread_self();
printf("set tid to: %lu\n", *buf);
return buf;
}
void tsd_test() {
unsigned long *tidp_a = store_tid();
printf("tid - before call another thread: %lu\n", *tidp_a);
int s;
pthread_t t2;
s = pthread_create(&t2, NULL, &store_tid, NULL);
if(s != 0) {
printf("failed to create thread\n");
exit(-1);
}
s = pthread_join(t2, NULL);
if(s != 0) {
printf("failed to join thread\n");
exit(-1);
}
printf("tid - after call another thread: %lu\n", *tidp_a);
}
int main(int argc, char *argv[]) {
tsd_test();
return 0;
}编译:
gcc -pthread tsd_test.c输出:
set tid to: 3076318976
tid - before call another thread: 3076318976
set tid to: 3076315968
destroy, tid: 3076315968
tid - after call another thread: 3076318976您可以看到,只有子线程打印“破坏”,而主线程没有。
发布于 2015-07-06 12:03:17
线程析构函数是在线程退出时调用的,而不是当进程死亡时--即当main()退出时--整个进程就会死。因此,析构函数不会被调用。
在pthread_exit(NULL);函数的末尾或者在tst()函数的末尾调用tst()函数(两者实际上是相同的)。现在,您将看到析构函数正在被调用。
https://stackoverflow.com/questions/31244806
复制相似问题