pthread_join函数项目里一般使用第二个参数都使用NULL,不关心线程执行后返回值,有同事发我一段程序,运行后程序segment,却找不到原因,鉴于此本文记录pthread_join的基本用法,文章末尾会给出这段程序,并分析原因。stackoverflow上有一个比较好的问答,介绍了pthread_exit和pthread_join组合使用的习惯用法:

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

void* thread_function(void *ignoredInThisExample)
{
    char *a = malloc(20);
    strcpy(a,"hello world");
    pthread_exit((void*)a);
}
int main()
{
    pthread_t thread_id;
    char *b;

    pthread_create (&thread_id, NULL,&thread_function, NULL);

    pthread_join(thread_id,(void**)&b); //here we are reciving one pointer
                                        //value so to use that we need double pointer
    printf("b is %s.\n",b);

    free(b); // lets free the memory

}

执行结果:

[root c++]#./pthread
b is hello world.

如果将程序修改成如下内容(thread_function函数去掉pthread_exit函数):

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

void* thread_function(void *ignoredInThisExample)
{
    char *a = malloc(20);
    strcpy(a,"hello world");
}
int main()
{
    pthread_t thread_id;
    char *b;

    pthread_create (&thread_id, NULL,&thread_function, NULL);

    pthread_join(thread_id,(void**)&b); //here we are reciving one pointer
                                        //value so to use that we need double pointer
    printf("b is %s.\n",b);

    return 0;
}

在gcc不同的优化选项下执行结果不同:

[root c++]#gcc -g -O0 -o pthread pthread.c -lpthread
[root c++]#./pthread
b is hello world.
[root c++]#
[root c++]#
[root c++]#gcc -g -O1 -o pthread pthread.c -lpthread
[root c++]#
[root c++]#
[root c++]#./pthread
b is .
[root c++]#gcc -g -O2 -o pthread pthread.c -lpthread
[root c++]#./pthread
b is .

之所以出现这样的结果是因为:%rax 作为函数返回值使用。没有pthread_exit语句,不同的优化级别 rax不一定是保留着a。