Linux开发

推荐列表 站点导航

当前位置:首页 > 服务器技术 > Linux开发 >

Linux下子线程exit code在主线程中的使用

来源:互联网  作者:网友投稿  发布时间:2021-01-06 17:22
Linux线程函数原型是这样的: void* thread_fun(void* arg) 它的返回值是 空类型指针,入口参数也是 空类型指针。那么线程...

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

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 等等,然后直接在主线程中使用类型转换到对应的数据类型就行了。

 

例如:

/***********************************

#     File Name: thread_cleanup2.c

#     Author   : lintex9527

#     E-Mail   : [email protected]

#  Created Time: Sat 22 Aug 2016 11:01:59 AM HKT

#  Purpose     : 

#  Outline     : 

#  Usage       : 

#               ------------------------------

#  Result      : 

#               ------------------------------

***********************************/

#include <stdio.h>

#include <stdlib.h>

#include <pthread.h>

void* thr_fn01(void *arg)

{

printf("thread 1 start:\n");

pthread_exit((void *)100);

pthread_exit((void *)"SOT-26"); // the first pthread_exit() works, the rest below that does not execute.

}

void* thr_fn02(void *arg)

{

printf("thread 2 start:\n"); 

pthread_exit((void *)"SOT-363");

}

int main(void)

{

int err;

pthread_t tid1, tid2;

void *tret;

pthread_create(&tid1, NULL, thr_fn01, (void *)1);

pthread_join(tid1, &tret);

printf("thread 1 exit code: %d\n", (tret));

printf("thread 1 exit code: %d\n", (int *)(tret));

pthread_create(&tid2, NULL, thr_fn02, (void *)1);

pthread_join(tid2, &tret);

printf("thread 2 exit code: %s\n", (tret));

printf("thread 2 exit code: %s\n", (char *)(tret));

return 0;

}

 

执行的结果如下:

$ ./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

 

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

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

 

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <pthread.h>

struct personStr{

char            name[30];

unsigned int    age;

char            sex; // 'M', 'W'

char            ID[30];

};

void printPerson(const char * str, struct personStr *p)

{

printf("%s\n", str);

printf("    name:%s\n", p->name);

printf("    age: %d\n", p->age);

printf("    sex: %c\n", p->sex);

printf("    ID:  %s\n", p->ID);

}

struct personStr thisman;

void* thr_fn01(void *arg)

{

printf("thread 1 start:\n");

memcpy(thisman.name, "Lee", strlen("Lee"));

thisman.age = 33;

thisman.sex = 'M';

memcpy(thisman.ID, "421127xxxx78455623", strlen("421127xxxx78455623"));

printPerson("In pthread 1:", &thisman);

pthread_exit((void *)&thisman);   

}

void* thr_fn02(void *arg)

{

printf("thread 2 start:\n");

pthread_exit((void *)"SOT-363");   

}

int main(void)

{

int err;

pthread_t tid1, tid2;

void *tret;

err = pthread_create(&tid1, NULL, thr_fn01, (void *)1);

pthread_join(tid1, &tret);

printPerson("In main thread:", tret);    // 直接使用指针

printPerson("In main thread:", (struct personStr *)tret);  // 强制类型转换为结构体指针

err = pthread_create(&tid2, NULL, thr_fn02, (void *)1);

pthread_join(tid2, &tret);

printf("thread 2 exit code: %s\n", (tret));

printf("thread 2 exit code: %s\n", (char *)(tret));

return 0;

}

 

执行结果如下:

$ ./thread_cleanup2.exe 

thread 1 start:

In pthread 1:

name:Lee

age: 33

sex: M

ID:  421127xxxx78455623

In main thread:

name:Lee

age: 33

sex: M

ID:  421127xxxx78455623

In main thread:

name:Lee

age: 33

sex: M

ID:  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 cast

cc -o thread_cleanup2.exe thread_cleanup2.o -lpthread

 

运行结果:

thread 1 exit code: 100

sizeof tret is 8 Bytes

sizeof(int) is 4 Bytes.

num = 100, num * 3 = 30

相关热词:

本站内容来源于网络,如有侵权请与我们联系,我们会及时删除,我们深感抱歉!
注:本站所有信息仅供用于网络技术学习参考,学习中请遵循相关法律法规!

本文地址: https://v30.fanwenzhu.com/server/kaifa/11527.shtml

相关文章
Copyright © www.juheyunku.com      关于 | 合作 | 声明 | 联系 | 更新 | 地图 | Tags

Linux下子线程exit code在主线程中的使用

2021-01-06 编辑:网友投稿

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

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 等等,然后直接在主线程中使用类型转换到对应的数据类型就行了。

 

例如:

/***********************************

#     File Name: thread_cleanup2.c

#     Author   : lintex9527

#     E-Mail   : [email protected]

#  Created Time: Sat 22 Aug 2016 11:01:59 AM HKT

#  Purpose     : 

#  Outline     : 

#  Usage       : 

#               ------------------------------

#  Result      : 

#               ------------------------------

***********************************/

#include <stdio.h>

#include <stdlib.h>

#include <pthread.h>

void* thr_fn01(void *arg)

{

printf("thread 1 start:\n");

pthread_exit((void *)100);

pthread_exit((void *)"SOT-26"); // the first pthread_exit() works, the rest below that does not execute.

}

void* thr_fn02(void *arg)

{

printf("thread 2 start:\n"); 

pthread_exit((void *)"SOT-363");

}

int main(void)

{

int err;

pthread_t tid1, tid2;

void *tret;

pthread_create(&tid1, NULL, thr_fn01, (void *)1);

pthread_join(tid1, &tret);

printf("thread 1 exit code: %d\n", (tret));

printf("thread 1 exit code: %d\n", (int *)(tret));

pthread_create(&tid2, NULL, thr_fn02, (void *)1);

pthread_join(tid2, &tret);

printf("thread 2 exit code: %s\n", (tret));

printf("thread 2 exit code: %s\n", (char *)(tret));

return 0;

}

 

执行的结果如下:

$ ./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

 

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

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

 

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <pthread.h>

struct personStr{

char            name[30];

unsigned int    age;

char            sex; // 'M', 'W'

char            ID[30];

};

void printPerson(const char * str, struct personStr *p)

{

printf("%s\n", str);

printf("    name:%s\n", p->name);

printf("    age: %d\n", p->age);

printf("    sex: %c\n", p->sex);

printf("    ID:  %s\n", p->ID);

}

struct personStr thisman;

void* thr_fn01(void *arg)

{

printf("thread 1 start:\n");

memcpy(thisman.name, "Lee", strlen("Lee"));

thisman.age = 33;

thisman.sex = 'M';

memcpy(thisman.ID, "421127xxxx78455623", strlen("421127xxxx78455623"));

printPerson("In pthread 1:", &thisman);

pthread_exit((void *)&thisman);   

}

void* thr_fn02(void *arg)

{

printf("thread 2 start:\n");

pthread_exit((void *)"SOT-363");   

}

int main(void)

{

int err;

pthread_t tid1, tid2;

void *tret;

err = pthread_create(&tid1, NULL, thr_fn01, (void *)1);

pthread_join(tid1, &tret);

printPerson("In main thread:", tret);    // 直接使用指针

printPerson("In main thread:", (struct personStr *)tret);  // 强制类型转换为结构体指针

err = pthread_create(&tid2, NULL, thr_fn02, (void *)1);

pthread_join(tid2, &tret);

printf("thread 2 exit code: %s\n", (tret));

printf("thread 2 exit code: %s\n", (char *)(tret));

return 0;

}

 

执行结果如下:

$ ./thread_cleanup2.exe 

thread 1 start:

In pthread 1:

name:Lee

age: 33

sex: M

ID:  421127xxxx78455623

In main thread:

name:Lee

age: 33

sex: M

ID:  421127xxxx78455623

In main thread:

name:Lee

age: 33

sex: M

ID:  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 cast

cc -o thread_cleanup2.exe thread_cleanup2.o -lpthread

 

运行结果:

thread 1 exit code: 100

sizeof tret is 8 Bytes

sizeof(int) is 4 Bytes.

num = 100, num * 3 = 30

本站内容来源于网络,如有侵权请与我们联系,我们会及时删除,我们深感抱歉!
注:本站所有信息仅供学习参考!
本文地址为 https://v30.fanwenzhu.com/server/kaifa/11527.shtml

相关文章

风云图片

推荐阅读

返回Linux开发频道首页