主要记录了一下使用pthread_join和pthread_exit这两个函数的时候出现的一些比较疑惑的地方。
首先先看一下这两个函数的原型:
#include <pthread.h>
int pthread_join(pthread_t thread, void **retval);
//看资料上,这个函数的作用是用来等待,讲述功能为“线程的等待”,调用该函数的线程,会发生阻塞,直到第一个参数中所填的线程返回,或调用pthread_exit函数,调用join函数的线程才会继续往下执行。
//第一个参数:线程ID
//第二个参数:是一个二级指针,用来获取线程ID为第一个参数的线程在调用pthread_exit后返回的返回值(也就是下面pthread_exit函数的参数void *retval)
void pthread_exit(void *retval);
/*线程退出
单个线程可以通过以下三种方式退出,在不终止整个进程的情况下停止它的控制流:
1)线程只是从启动例程中返回,返回值是线程的退出码。
2)线程可以被同一进程中的其他线程取消。
3)线程调用pthread_exit:
*/
//所以这个函数的作用就是用来退出线程的,而后面的参数就是退出这个线程以后,想返回的返回值,要注意的是,这返回值是一个指针。
.
而我在使用的过程中感觉比较难懂的地方就是这个返回值了,不太好表达,先上代码和执行结果,再进行对比分析吧。
.
代码A:
void *fun1(void *arg)
{
static char *ret_str = "fun1 exit\n";
printf("------the following content is from fun1------\n");
printf("val=%d\n",*((int *)arg));
printf("fun1 thread id:%ld\n",(unsigned long)pthread_self());
pthread_exit(ret_str);
}
int main()
{
pthread_t t1;
int val = 10;
char *ret_fun1 = NULL;
pthread_create(&t1,NULL,fun1,(void *)&val);
printf("main thread id:%ld\n",(unsigned long)pthread_self());
pthread_join(t1,(void **)&ret_fun1); //疑问点1
printf("ret_fun1:%s\n",ret_fun1);
}
.
代码B:
void *fun1(void *arg)
{
static int ret_int = 81;
printf("------the following content is from fun1------\n");
printf("val=%d\n",*((int *)arg));
printf("fun1 thread id:%ld\n",(unsigned long)pthread_self());
pthread_exit(&ret_int);
}
int main()
{
pthread_t t1;
int val = 10;
int *ret_fun1 = NULL;
pthread_create(&t1,NULL,fun1,(void *)&val);
printf("main thread id:%ld\n",(unsigned long)pthread_self());
pthread_join(t1,(void **)&ret_fun1); //疑问点1
printf("ret_fun1:%d\n",*(ret_fun1));
从上面可以看到,代码B中返回的是int型的数,pthread_join的第二个参数是二级指针,代码B中打印ret_fun1的时候前面是需要加“*”来取内容的,而在代码A中,返回的是char 型的,是字符串,代码A中打印ret_fun1的时候前面是不需要加“”来取内容的,这个很明显嘛,字符串本来就是地址,这没什么疑问的,但有疑问的地方是,为什么&ret_fun1这个指针就指向ret_int的地址或者指向ret_str呢?join到底进行了什么操作?
这图是我从别人的博客上找到的,pthread_join的源码的一部分,看到框起来的那一句以后我才明白这个返回值到底是什么获取的,知道了怎么获取的,也就方便日后用到这个函数的时候,获取返回值就不会不知道这参数到底怎么填了,还有打印的时候为什么要这样写。
看图中框住的地方,可以发现原来是没有理解到指针的这个用法,用法:二级指针的前面加个*,然后再让“*二级指针=一级指针”,这个是可行的,这里就相当于,把二级指针原本指向的内存单元,改为了等号后面的那个一级指针。再通俗点讲,【就是二级指针原本是指向ret_fun1的,经过那条语句以后,二级指针就指向ret_int了】
下面是自己画的一个草图:
要注意的是,这个图要结合上面的代码看的
既然我会这么确定,那必须得上点证明才行啊
下面是证明的代码:
然后是运行结果:
OK,纠结了一晚上才想通了的,浪费了好多时间,希望以后不会忘掉吧。