官方说法:

函数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*),传地址进去接值是接口类函数常用的做法,有同样效果的做法是引用&,但是这个做法一来值容易被误改,二来不规范,所以定义一个类型然后把地址传进去修改value。回到题目,这里返回的void*是一个指针类型,必须强转成对应的指针才能用。

举个例子,如果是char* = “mimida”;传出来的tmp,必须(char*)tmp一下。

而如果是int* a = new(3888);这种类型返回的tmp,必须*(int*)tmp一下才能用。

最重要的一点,你定义的类型和最后出来的类型一定要一致,不然很容易出现问题。也就是你定义了int*,最后强转出来的一定是*(int*)。

别void* a = (void*)10;这种诡异的格式(我就中过招),一开始是什么就转成什么!(这个规则同时也适用于线程数据里的set和get)

实例如下:

  1. <pre name="code" class="cpp">/* example.c*/
  2. #include <stdio.h>
  3. #include <pthread.h>
  4. void thread1(char s[])
  5. {
  6. printf("This is a pthread1.\n");
  7. printf("%s\n",s);
  8. pthread_exit((void*)"the first return!");  //结束线程,返回一个值。
  9. }
  10. void thread2(char s[])
  11. {
  12. int *a = new(46666);
  13. <span style="white-space:pre">    </span>printf("This is a pthread2.\n");
  14. printf("%s\n",s);
  15. pthread_exit((void*)a);
  16. }
  17. /**************main function ****************/
  18. int main(void)
  19. {
  20. pthread_t id1,id2;
  21. void *a1,*a2;
  22. int i,ret1,ret2;
  23. char s1[]="This is first thread!";
  24. char s2[]="This is second thread!";
  25. ret1=pthread_create(&id1,NULL,(void *) thread1,s1);
  26. ret2=pthread_create(&id2,NULL,(void *) thread2,s2);
  27. if(ret1!=0){
  28. printf ("Create pthread1 error!\n");
  29. exit (1);
  30. }
  31. pthread_join(id1,&a1);
  32. printf("%s\n",(char*)a1);
  33. if(ret2!=0){
  34. printf ("Create pthread2 error!\n");
  35. exit (1);
  36. }
  37. printf("This is the  main process.\n");
  38. pthread_join(id2,&a2);
  39. printf("%s\n",*(int*)a2);
  40. return (0);
  41. }

运行结果: 
[****@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

http://blog.csdn.net/modiziri/article/details/41961595

pthread_join/pthread_exit的用法解析的更多相关文章

  1. extern "c"用法解析

    转自: extern "c"用法解析 - 简书 引言 C++保留了一部分过程式语言的特点,因而它可以定义不属于任何类的全局变量和函数.但是,C++毕竟是一种面向对象的程序设计语言, ...

  2. WordPress的have_posts()和the_post()用法解析

    原文地址:http://www.phpvar.com/archives/2316.html 网上找到一篇介绍WordPress的have_posts()和the_post()用法解析的文章,觉得不错! ...

  3. extern "C" 用法解析

    extern "c"用法解析 作者 作者Jason Ding ,链接http://www.jianshu.com/p/5d2eeeb93590 引言 C++保留了一部分过程式语言的 ...

  4. mysql group by 用法解析(详细)

    在使用mysql时,有时需要查询出某个字段不重复的记录,虽然mysql提供 有distinct这个关键字来过滤掉多余的重复记录只保留一条,但往往只用它来返回不重复记录的条数,而不是用它来返回不重记录的 ...

  5. (转载)mysql group by 用法解析(详细)

    (转载)http://blog.tianya.cn/blogger/post_read.asp?BlogID=4221189&PostID=47881614 mysql distinct 去重 ...

  6. group by 用法解析

    group by 用法解析 group by语法可以根据给定数据列的每个成员对查询结果进行分组统计,最终得到一个分组汇总表. SELECT子句中的列名必须为分组列或列函数.列函数对于GROUP BY子 ...

  7. sql中的group by 和 having 用法解析

    转载博客:http://www.cnblogs.com/wang-123/archive/2012/01/05/2312676.html --sql中的group by 用法解析:-- Group B ...

  8. C/C++之extern "C"的用法解析

    extern "C"的用法解析 http://blog.sina.com.cn/u/494a1ebc010004g5 C++中extern “C”含义深层探索 1.引言 C++语言 ...

  9. ZT extern "C"的用法解析

    extern "C"的用法解析 1.引言 C++语言的创建初衷是“a better C”,但是这并不意味着C++中类似C语言的全局变量和函数所采用的编译和连接方式与C语言完全相同. ...

随机推荐

  1. (转)硬盘结构,主引导记录MBR,硬盘分区表DPT,主分区、扩展分区和逻辑分区,电脑启动过程

    硬盘结构硬盘有很多盘片组成,每个盘片的每个面都有一个读写磁头.如果有N个盘片.就有2N个面,对应2N个磁头(Heads),从0.1.2开始编号.每个盘片的半径均为固定值R的同心圆再逻辑上形成了一个以电 ...

  2. [置顶] Elon Musk (伊隆·马斯克):无限的创想与意志的胜利

    Elon Musk (伊隆·马斯克):无限的创想与意志的胜利 很多人说 Steve Jobs 很伟大,这一点我认同.但是,单纯从创造出的产物而言,Elon Musk 的成就毫无疑问远远超越 Steve ...

  3. HDU 1575 Tr A( 简单矩阵快速幂 )

    链接:传送门 思路:简单矩阵快速幂,算完 A^k 后再求一遍主对角线上的和取个模 /********************************************************** ...

  4. BZOJ 2118 墨墨的等式 (同余最短路)

    题目大意:已知B的范围,求a1x1+a2x2+...+anxn==B存在非负正整数解的B的数量,N<=12,ai<=1e5,B<=1e12 同余最短路裸题 思想大概是这样的,我们选定 ...

  5. [luogu2501 HAOI2006] 数字序列 (递推LIS)

    题目描述 现在我们有一个长度为n的整数序列A.但是它太不好看了,于是我们希望把它变成一个单调严格上升的序列.但是不希望改变过多的数,也不希望改变的幅度太大. 输入输出格式 输入格式: 第一行包含一个数 ...

  6. (原创)Java 读取 Highcharts 中的图片

    前言:项目中提出一个新需求,就将Highcharts中的图片读取到Excel中.并在前台做下载,当听到这功能,第一想法是需要由后台编写程序,将数据写道图片中. 虽然没做过但是也没觉得太难,毕竟前辈们肯 ...

  7. linux下的查找命令

    whereis <程序名称> 查找软件的安装路径 -b 只查找二进制文件 -m 只查找帮助文件 -s 只查找源代码 -u 排除指定类型文件 -f 只显示文件名 -B <目录> ...

  8. Laravel核心解读--Contracts契约

    Contracts Laravel 的契约是一组定义框架提供的核心服务的接口, 例如我们在介绍用户认证的章节中到的用户看守器契约IllumninateContractsAuthGuard 和用户提供器 ...

  9. vue中的生命周期

    vue中的生命周期 1,vue生命周期简介: 1.beforeCreate 在实例初始化之后,数据观测和event/watcher时间配置之前被调用.   2.created 实例已经创建完成之后被调 ...

  10. webpack加载器(Loaders)

    加载器(Loaders) loader 是对应用程序中资源文件进行转换.它们是(运行在 Node.js 中的)函数,可以将资源文件作为参数的来源,然后返回新的资源文件. 示例 例如,你可以使用 loa ...