官方说法:
函数pthread_join用来等待一个线程的结束。函数原型为:
extern int pthread_join __P ((pthread_t __th, void **__thread_return));第一个參数为被等待的线程标识符,第二个參数为一个用户定义的指针,它能够用来存储被等待线程的返回值。这个函数是一个线程堵塞的函数,调用它的线程将一直等待到被等待的线程结束为止,当函数返回时,被等待线程的资源被收回。一个线程的结束有两种途径,一种是象我们上面的样例一样,函数结束了,调用它的线程也就结束了;
还有一种方式是通过函数pthread_exit来实现。它的函数原型为:
extern void pthread_exit __P ((void *__retval)) __attribute__ ((__noreturn__));唯一的參数是函数的返回代码,仅仅要pthread_exit中的參数retval不是NULL,这个值将被传递给 thread_return。最后要说明的是,一个线程不能被多个线程等待,否则第一个接收到信号的线程成功返回,其余调用pthread_join的线程则返回错误代码ESRCH。
上面说的有点乱,看不懂的看这里:
pthread_join用于等待一个线程的结束,也就是主线程中要是加了这段代码,就会在加代码的位置卡主,直到这个线程运行完成才往下走。
pthread_exit用于强制退出一个线程(非运行完成退出),一般用于线程内部。
结合使用方法:
一般都是pthread_exit在线程内退出,然后返回一个值。这个时候就跳到主线程的pthread_join了(由于一直在等你结束),这个返回值会直接送到pthread_join,实现了主与分线程的通信。
注意事项:
这个线程退出的返回值的格式是void*,不管是什么格式都要强转成void*才干返回出来主线程(pthread_exit((void*)tmp);),而这个时候pthread_join就去接这个值,我们传进去一个void*的地址也就是&(void*),传地址进去接值是接口类函数经常使用的做法,有相同效果的做法是引用&,可是这个做法一来值easy被误改,二来不规范,所以定义一个类型然后把地址传进去改动value。回到题目,这里返回的void*是一个指针类型,必须强转成相应的指针才干用。
举个样例,假设是char* = “mimida”;传出来的tmp,必须(char*)tmp一下。
而假设是int* a = new(3888);这样的类型返回的tmp,必须*(int*)tmp一下才干用。
最重要的一点,你定义的类型和最后出来的类型一定要一致,不然非常easy出现故障。也就是你定义了int*,最后强转出来的一定是*(int*)。
别void* a = (void*)10;这样的诡异的格式(我就中过招),一開始是什么就转成什么!(这个规则同一时候也适用于线程数据里的set和get)
实比例如以下:
<pre name="code" class="cpp">/* example.c*/ #include <stdio.h> #include <pthread.h> void thread1(char s[]) { printf("This is a pthread1. "); printf("%s ",s); pthread_exit((void*)"the first return!"); //结束线程,返回一个值。 } void thread2(char s[]) { int *a = new(46666); <span style="white-space:pre"> </span>printf("This is a pthread2. "); printf("%s ",s); pthread_exit((void*)a); } /**************main function ****************/ int main(void) { pthread_t id1,id2; void *a1,*a2; int i,ret1,ret2; char s1[]="This is first thread!"; char s2[]="This is second thread!"; ret1=pthread_create(&id1,NULL,(void *) thread1,s1); ret2=pthread_create(&id2,NULL,(void *) thread2,s2); if(ret1!=0){ printf ("Create pthread1 error! "); exit (1); } pthread_join(id1,&a1); printf("%s ",(char*)a1); if(ret2!=0){ printf ("Create pthread2 error! "); exit (1); } printf("This is the main process. "); pthread_join(id2,&a2); printf("%s ",*(int*)a2); return (0); }
执行结果:
[****@XD**** c]$ ./example
This is a pthread1.
This is first thread!
the
first return!
This is the main process.
This is a pthread2.
This is second thread!
46666