Linux线程函数原型是这样的:

1 void* thread_fun(void* arg)

它的返回值是 空类型指针,入口参数也是 空类型指针。那么线程的 exit code 也应该是 void * 类型的。但是在主线程怎么捕获子线程的 exit code 并使用的呢?

捕获的思路如下:

1. 在主线程中定义一个 void* tret;

2. 使用 pthread_join(tidxx, &tret);

这样就能够捕获到子线程的 exit code。

但是如何使用呢?这就取决于子线程中的 exit code 具体表示的数据类型了,可以是 int, char *, struct xxxStr 等等,然后直接在主线程中使用类型转换到对应的数据类型就行了。

例如:

 1 /****************************************************************
 2 #     File Name: thread_cleanup2.c
 3 #     Author   : lintex9527
 4 #     E-Mail   : lintex9527@yeah.net
 5 #  Created Time: Sat 22 Aug 2015 11:01:59 AM HKT
 6 #  Purpose     :
 7 #  Outline     :
 8 #  Usage       :
 9 #               --------------------------------------------------
10 #  Result      :
11 #               --------------------------------------------------
12 *****************************************************************/
13
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <pthread.h>
17
18 void* thr_fn01(void *arg)
19 {
20     printf("thread 1 start:\n");
21     pthread_exit((void *)100);
22     pthread_exit((void *)"SOT-26"); // the first pthread_exit() works, the rest below that does not execute.
23 }
24
25 void* thr_fn02(void *arg)
26 {
27     printf("thread 2 start:\n");
28     pthread_exit((void *)"SOT-363");
29 }
30
31 int main(void)
32 {
33     int err;
34     pthread_t tid1, tid2;
35     void *tret;
36
37     pthread_create(&tid1, NULL, thr_fn01, (void *)1);
38     pthread_join(tid1, &tret);
39     printf("thread 1 exit code: %d\n", (tret));
40     printf("thread 1 exit code: %d\n", (int *)(tret));
41
42     pthread_create(&tid2, NULL, thr_fn02, (void *)1);
43     pthread_join(tid2, &tret);
44     printf("thread 2 exit code: %s\n", (tret));
45     printf("thread 2 exit code: %s\n", (char *)(tret));
46
47     return 0;
48 }

执行的结果如下:

 $ ./thread_cleanup2.exe
thread 1 start:
thread 1 exit code: 100
thread 1 exit code: 100
thread 2 start:
thread 2 exit code: SOT-363
thread 2 exit code: SOT-363

可以看到“直接使用指针方式” 和 “强制类型转换方式” 输出的结果都一样。

上面的都是基本数据类型方式,那么再试一下其他的数据类型,例如结构体:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 #include <pthread.h>
 5
 6
 7 struct personStr{
 8     char            name[30];
 9     unsigned int    age;
10     char            sex; // 'M', 'W'
11     char            ID[30];
12 };
13
14 void printPerson(const char * str, struct personStr *p)
15 {
16     printf("%s\n", str);
17     printf("    name:%s\n", p->name);
18     printf("    age: %d\n", p->age);
19     printf("    sex: %c\n", p->sex);
20     printf("    ID:  %s\n", p->ID);
21 }
22
23 struct personStr thisman;
24
25 void* thr_fn01(void *arg)
26 {
27     printf("thread 1 start:\n");
28     memcpy(thisman.name, "Lee", strlen("Lee"));
29     thisman.age = 33;
30     thisman.sex = 'M';
31     memcpy(thisman.ID, "421127xxxx78455623", strlen("421127xxxx78455623"));
32     printPerson("In pthread 1:", &thisman);
33
34     pthread_exit((void *)&thisman);
35 }
36
37 void* thr_fn02(void *arg)
38 {
39     printf("thread 2 start:\n");
40     pthread_exit((void *)"SOT-363");
41
42 }
43
44 int main(void)
45 {
46     int err;
47     pthread_t tid1, tid2;
48     void *tret;
49
50     err = pthread_create(&tid1, NULL, thr_fn01, (void *)1);
51     pthread_join(tid1, &tret);
52     printPerson("In main thread:", tret);    // 直接使用指针
53     printPerson("In main thread:", (struct personStr *)tret);  // 强制类型转换为结构体指针
54
55     err = pthread_create(&tid2, NULL, thr_fn02, (void *)1);
56     pthread_join(tid2, &tret);
57     printf("thread 2 exit code: %s\n", (tret));
58     printf("thread 2 exit code: %s\n", (char *)(tret));
59
60     return 0;
61 }

执行结果如下:

$ ./thread_cleanup2.exe
thread 1 start:
In pthread 1:name:Leeage: 33sex: MID:  421127xxxx78455623
In main thread:name:Leeage: 33sex: MID:  421127xxxx78455623
In main thread:name:Leeage: 33sex: MID:  421127xxxx78455623
thread 2 start:
thread 2 exit code: SOT-363
thread 2 exit code: SOT-363

可以看到 “直接使用指针” 和 “强制类型转换”结果都是一样的。如果图方便就直接使用指针,而且这样的代码通用性也好,万一将来某天结构体名字变动了,就需要改动很多地方了,但是也有弊病,就是代码的易读性不好。

有一点奇怪的就是第一个例子中,为什么返回的是整数 int 类型的"100",却能通过指针打印出"100"呢?

这样验证:

printf("thread 1 exit code: %d\nsizeof tret is %d Bytes\nsizeof(int) is %d Bytes.\n", (tret), sizeof(tret), sizeof(int));

结果是这样的:

thread 1 exit code: 100
sizeof tret is 8 Bytes
sizeof(int) is 4 Bytes.

那么就说明 tret 的确是指针类型的,占用了8个字节的数据,而 int 类型的数据只占用了4个字节,而且进行如下的尝试,编译失败了:

printf("tret * 3 = %d\n", tret * 3);
很不幸,失败了,结果:
thread_cleanup2.c:93: error: invalid operands to binary * (have ‘void *’ and ‘int’)
make: *** [thread_cleanup2.o] Error 1

如果的确是想使用 tret 的值100, 可否通过指针取值运算呢?

printf("tret * 3 = %d\n", (*((int *)tret)) * 3);很不幸,这样也失败了。

如果要想把返回值 tret 参与其他的运算,就必须使用一个转换的桥梁。利用 “中间变量 = tret”,然后使用这个中间变量,虽然编译会有 warning 提醒,但是的确能使用:

//printf("tret * 3 = %d\n", (*((int *)tret)) * 3);// failed.
//int num = *((int *)tret); // failed.
int num = tret;
printf("num = %d, num * 3 = %d\n", num, num * 3 );

编译提示:thread_cleanup2.c:95: warning: initialization makes integer from pointer without a castcc -o thread_cleanup2.exe thread_cleanup2.o -lpthread

运行结果:thread 1 exit code: 100sizeof tret is 8 Bytessizeof(int) is 4 Bytes.num = 100, num * 3 = 30

2015-08-22 13:17:12 于公司。

转载于:https://www.cnblogs.com/LinTeX9527/p/4750083.html

Linux 下子线程 exit code 在主线程中的使用相关推荐

  1. UnityThread子线程使用只能在主线程中调用的函数或Unity API

    Unity的Socket网络编程中,为了防止程序卡死,一般使用多线程来监听端口,当收到来自客户端的消息时,需要显示在界面上.但是如果直接在子线程中操作Unity的界面或物体会报错.国外一个大神写了一个 ...

  2. 每个java程序都至少有一个线程给主线程,java程序在主线程中判断各个子线程状态的操作,该如何解决...

    java程序在主线程中判断各个子线程状态的操作 每个子线程在队列为空时会wait等待其他线程添加新url到队列,到最后所有子线程都取不到url时也会都wait住,要在主线程中判断如果所有的子线程都是w ...

  3. java 子线程退出_java – 在子线程完成执行之前主线程将退出吗?

    我读了2篇文章 在上面的文章中,在"线程终止"段中,它在Red中声明"如果父线程终止,它的所有子线程也会终止". 在上面的文章中,该页面的最后一行指出" ...

  4. C语言:记录在主线程中停止子线程

    主线程中创建一个子线程如代码: #include <stdio.h> #include <pthread.h> #include <unistd.h> #inclu ...

  5. 用Handler的post()方法来传递线程中的代码段到主线程中执行

    自定义的线程中是不能更新UI的,但是如果遇到更新UI的事情,我们可以用handler的post()方法来将更新UI的方法体,直接传送到主线程中,这样就能直接更新UI了.Handler的post()方法 ...

  6. 【Android 异步操作】Android 线程切换 ( 判定当前线程是否是主线程 | 子线程中执行主线程方法 | 主线程中执行子线程方法 )

    文章目录 一.判定当前线程是否是主线程 二.子线程中执行主线程方法 三.主线程中执行子线程方法 一.判定当前线程是否是主线程 在 Android 中 , 如果要判定当前线程是否是主线程 , 可以使用如 ...

  7. Android中Handler消息传递机制应用之子线程不允许操作主线程的组件

    场景 进程 一个Android应用就是一个一个进程,每个应用在各自的进程中运行. 线程 比进程更小的独立运行的基本单位,一个进程可以包含多个线程. 要求 一个TextView和一个Button,点击B ...

  8. android不能在主线程,安卓开发:主线程真的不能做UI操作吗?这一点很多程序员都没想到...

    只要参与过安卓项目开发一两年的朋友们应该清楚,为了避免UI渲染出现异常安卓框架限制UI操作只能在主线程中进行,如果贸然在子线程做了UI操作结果会怎样?我们随便写下了如下测试代码. 不出意外的话,代码执 ...

  9. 在子线程中更改主线程中的控件的信息,在子线程中用toast

    一丶在子线程中不允许更改主线程中的控件的信息,也不允许在子线程中用toast,我们要更改的话 (1)消息机制:使用handler (由主线程调用) 在主程序中Handler handler = new ...

  10. 在主线程中为子线程解锁_在XP中为Google Chrome启用Vista黑色风格主题

    在主线程中为子线程解锁 If you've seen the screenshots of Google Chrome on XP vs Vista, you've probably noticed ...

最新文章

  1. Python 的基本数据类型
  2. 呵呵,哈哈,嘿嘿,从今天起就开始写博客文了
  3. ERROR 1222 (21000): The used SELECT statements have a different number of columns :
  4. python eval()函数用法以及可能出现的问题
  5. halcon 3D Object Model 三维物体模型算子,持续更新
  6. 新型互联网交换中心促进互联网产业发展,助力信息经济创新
  7. NeurlPS 2019丨微软亚洲研究院 5 篇精选论文解读
  8. idea 中maven编译速度过慢的问题的解决
  9. MediaInfo源代码分析 2:API函数
  10. sessionid如何产生?由谁产生?保存在哪里?
  11. Keymob移动网盟与芒果移动网盟的对比
  12. SSH隧道putty使用
  13. html自动写对联,html+css纯代码给自己的网站添加对联广告位
  14. 【图像处理】图像锐化
  15. MaterialDrawer库的Gradle配置
  16. h5唤起App两种方式 Schema Universal Link
  17. element ui 上一页下一页_vue翻页器,包括上一页,下一页,跳转
  18. 单台电脑jmeter压力测试最大值
  19. 给PPT插入页码和总页码
  20. 快速矩阵乘法的研究——下

热门文章

  1. python属性是什么意思_什么是python类属性
  2. dedecms设置端口号_织梦程序使用宝塔面板端口修改方法
  3. 生成word_用Word生成员工信息表,单独生成独立文件,还能自动命名
  4. 设计模式C++(Strategy策略模式)
  5. java ee自学_自学JavaEE难度大不大?
  6. 神经结构化学习 4 图像分类的对抗性学习Adversarial learning for image classification
  7. 实战RxSwift中的Observable, subscribe, dispose, filter
  8. 《领域驱动设计精粹》DDD Domain-Driven Design Distilled -- Vaughn Vernon 读后感
  9. 电脑电子版文件怎么弄_清空回收站后,如何找回删除的文件?
  10. 代码整洁之道读书笔记----第三章---函数--第一节-专注且短小