pthread_key_create() - 何时调用`析构函数`函数?

时间:2015-07-06 11:33:48

标签: c linux multithreading pthreads

我写了一个程序来了解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”,而主线程没有。

1 个答案:

答案 0 :(得分:5)

当线程退出时调用线程析构函数,而不是当进程终止时,即当main()退出时,整个进程终止。所以析构函数不会被调用。

pthread_exit(NULL);函数末尾或末尾main()函数(两者都相同)中调用tst()。现在,您将看到被调用的析构函数。