【发布时间】:2015-09-23 12:55:18
【问题描述】:
我编写了一个程序来了解 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
可以看到只有子线程打印“destroy”,而主线程没有。
【问题讨论】:
-
OT:pthread函数需要的签名是
void*(*)(void*),所以应该是void *store_tid(void*)。编译所有警告(-Wall -Wextra -pedanticfor gcc)以获得此类问题的通知。 -
@alk 明白了,很好的提示。
标签: c linux multithreading pthreads