Linux 下子线程 exit code 在主线程中的使用
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 在主线程中的使用相关推荐
- UnityThread子线程使用只能在主线程中调用的函数或Unity API
Unity的Socket网络编程中,为了防止程序卡死,一般使用多线程来监听端口,当收到来自客户端的消息时,需要显示在界面上.但是如果直接在子线程中操作Unity的界面或物体会报错.国外一个大神写了一个 ...
- 每个java程序都至少有一个线程给主线程,java程序在主线程中判断各个子线程状态的操作,该如何解决...
java程序在主线程中判断各个子线程状态的操作 每个子线程在队列为空时会wait等待其他线程添加新url到队列,到最后所有子线程都取不到url时也会都wait住,要在主线程中判断如果所有的子线程都是w ...
- java 子线程退出_java – 在子线程完成执行之前主线程将退出吗?
我读了2篇文章 在上面的文章中,在"线程终止"段中,它在Red中声明"如果父线程终止,它的所有子线程也会终止". 在上面的文章中,该页面的最后一行指出" ...
- C语言:记录在主线程中停止子线程
主线程中创建一个子线程如代码: #include <stdio.h> #include <pthread.h> #include <unistd.h> #inclu ...
- 用Handler的post()方法来传递线程中的代码段到主线程中执行
自定义的线程中是不能更新UI的,但是如果遇到更新UI的事情,我们可以用handler的post()方法来将更新UI的方法体,直接传送到主线程中,这样就能直接更新UI了.Handler的post()方法 ...
- 【Android 异步操作】Android 线程切换 ( 判定当前线程是否是主线程 | 子线程中执行主线程方法 | 主线程中执行子线程方法 )
文章目录 一.判定当前线程是否是主线程 二.子线程中执行主线程方法 三.主线程中执行子线程方法 一.判定当前线程是否是主线程 在 Android 中 , 如果要判定当前线程是否是主线程 , 可以使用如 ...
- Android中Handler消息传递机制应用之子线程不允许操作主线程的组件
场景 进程 一个Android应用就是一个一个进程,每个应用在各自的进程中运行. 线程 比进程更小的独立运行的基本单位,一个进程可以包含多个线程. 要求 一个TextView和一个Button,点击B ...
- android不能在主线程,安卓开发:主线程真的不能做UI操作吗?这一点很多程序员都没想到...
只要参与过安卓项目开发一两年的朋友们应该清楚,为了避免UI渲染出现异常安卓框架限制UI操作只能在主线程中进行,如果贸然在子线程做了UI操作结果会怎样?我们随便写下了如下测试代码. 不出意外的话,代码执 ...
- 在子线程中更改主线程中的控件的信息,在子线程中用toast
一丶在子线程中不允许更改主线程中的控件的信息,也不允许在子线程中用toast,我们要更改的话 (1)消息机制:使用handler (由主线程调用) 在主程序中Handler handler = new ...
- 在主线程中为子线程解锁_在XP中为Google Chrome启用Vista黑色风格主题
在主线程中为子线程解锁 If you've seen the screenshots of Google Chrome on XP vs Vista, you've probably noticed ...
最新文章
- Python 的基本数据类型
- 呵呵,哈哈,嘿嘿,从今天起就开始写博客文了
- ERROR 1222 (21000): The used SELECT statements have a different number of columns :
- python eval()函数用法以及可能出现的问题
- halcon 3D Object Model 三维物体模型算子,持续更新
- 新型互联网交换中心促进互联网产业发展,助力信息经济创新
- NeurlPS 2019丨微软亚洲研究院 5 篇精选论文解读
- idea 中maven编译速度过慢的问题的解决
- MediaInfo源代码分析 2:API函数
- sessionid如何产生?由谁产生?保存在哪里?
- Keymob移动网盟与芒果移动网盟的对比
- SSH隧道putty使用
- html自动写对联,html+css纯代码给自己的网站添加对联广告位
- 【图像处理】图像锐化
- MaterialDrawer库的Gradle配置
- h5唤起App两种方式 Schema Universal Link
- element ui 上一页下一页_vue翻页器,包括上一页,下一页,跳转
- 单台电脑jmeter压力测试最大值
- 给PPT插入页码和总页码
- 快速矩阵乘法的研究——下
热门文章
- python属性是什么意思_什么是python类属性
- dedecms设置端口号_织梦程序使用宝塔面板端口修改方法
- 生成word_用Word生成员工信息表,单独生成独立文件,还能自动命名
- 设计模式C++(Strategy策略模式)
- java ee自学_自学JavaEE难度大不大?
- 神经结构化学习 4 图像分类的对抗性学习Adversarial learning for image classification
- 实战RxSwift中的Observable, subscribe, dispose, filter
- 《领域驱动设计精粹》DDD Domain-Driven Design Distilled -- Vaughn Vernon 读后感
- 电脑电子版文件怎么弄_清空回收站后,如何找回删除的文件?
- 代码整洁之道读书笔记----第三章---函数--第一节-专注且短小