pthread_exit 参数使用
来源:互联网 发布:java可控参数 编辑:程序博客网 时间:2024/06/11 03:59
原型:
#include<pthread.h>
void pthread_exit(void *rval_ptr); //退出线程,参数是个空类型的指针保存的是线程退出以后的返回值
int pthread_join(pthread_t thread ,void **rval_ptr);//以阻塞方式等待thread指定线程结束,参数thread是需要等待的线程ID,rval_ptr是用户定义的指针,用来 存储被等待线程的返回值
void pthread_exit(void *rval_ptr);这个函数的功能就是使一个线程正常退出,终止线程,因为我们知道线程它是依赖进程存在的,如果在线程中使用exit()函数退出,那么整个的进程将会退出,如果此时创建该线程的进程还有一些其它的事情没有完成,所以这并不是我们所希望的。这个参数保存的是线程退出以后返回的值。当然这个参数传递的数值可以不止一个,比如 该我们想传递好几个参数怎么办呢,很快我们就能够想到我们所学过的结构体呀之类的,这时问题就来了,需要注意的问题是:这个结构所使用的内存在调用者完成调用以后必须仍然是有效的,否则就会出现非法访问内存。例如在线程栈上分配了该结构,那么其他的线程在是用这个结构时内存内容可能已经改变了。又如,线程在自己的栈上分配了一个结构然后把指向这个结构的指针传给pthread_exit(),那么当调用pthread_join的线程试图使用该结构时,这个栈有可能已经被撤销,这块内存也已令做他用。
EG:pthread_exit 参数不正确使用
运行结果如下:
wangye@wangye:~$ gcc -g -lpthread text1.c libapue.a
wangye@wangye:~$ ./a.out
thread 1:
structure at 0xb75dc380
foo.a = 1
foo.b = 2
foo.c = 3
foo.d = 4
parent starting second thread
thread 2: ID is 3076377456
parent:
structure at 0xb75dc380
foo.a = 3077489678
foo.b = 3076375444
foo.c = 3077709812
foo.d = 3077702244
#include "apue.h"#include <pthread.h>struct foo { int a, b, c, d;};void printfoo(const char *s, const struct foo *fp){ printf(s); printf(" structure at 0x%x\n", (unsigned)fp); printf(" foo.a = %u\n", fp->a); printf(" foo.b = %u\n", fp->b); printf(" foo.c = %u\n", fp->c); printf(" foo.d = %u\n", fp->d);}void * thr_fn1(void *arg){ struct foo foo = {1, 2, 3, 4}; printfoo("thread 1:\n", &foo); pthread_exit((void *)&foo);}void * thr_fn2(void *arg){ printf("thread 2: ID is %u\n", pthread_self()); pthread_exit((void *)0);}int main(void){ int err; pthread_t tid1, tid2; struct foo *fp; err = pthread_create(&tid1, NULL, thr_fn1, NULL); if (err != 0) err_quit("can't create thread 1: %s\n", strerror(err)); err = pthread_join(tid1, (void *)&fp);//线程在自己的栈上分配了一个结构然后把指向这个结构的指针传给pthread_exit(),那么当调用pthread_join的线程试 图使用该结构时,这个栈有已经被撤销,这块内存也已令做他用,fp指针就变成野指针。 if (err != 0) err_quit("can't join with thread 1: %s\n", strerror(err)); sleep(1); printf("parent starting second thread\n"); err = pthread_create(&tid2, NULL, thr_fn2, NULL); if (err != 0) err_quit("can't create thread 2: %s\n", strerror(err)); sleep(1); printfoo("parent:\n", fp); exit(0);}
运行结果如下:
wangye@wangye:~$ gcc -g -lpthread text1.c libapue.a
wangye@wangye:~$ ./a.out
thread 1:
structure at 0xb75dc380
foo.a = 1
foo.b = 2
foo.c = 3
foo.d = 4
parent starting second thread
thread 2: ID is 3076377456
parent:
structure at 0xb75dc380
foo.a = 3077489678
foo.b = 3076375444
foo.c = 3077709812
foo.d = 3077702244
结果根本不是我们所想到的,其实学过C语言,这个问题也不难想,因为foo这个局部变量是在栈上面分配的,而我们知道,函数在返回或退出的时候,这些局部变量就会自动被释放,所以返回给主函数的还是一个野指针。这里我们需要知道的另一个知识点就是,每个线程之间的栈是相互独立的,每个线程都拥有自己的栈区,虽然说它们的栈都是从进程空间的栈中分配的并且共享进程的栈,但是在创建线程的时候,每个线程都从进程栈区那儿获得一个私有的栈区。
处理上面的出现的问题办法就是,使用全局结构或malloc动态分配内存;
改为全局变量的例子:
#include "apue.h"#include <pthread.h>struct foo { int a, b, c, d;}; struct foo foo = {1, 2, 3, 4};void printfoo(const char *s, const struct foo *fp){ printf(s); printf(" structure at 0x%x\n", (unsigned)fp); printf(" foo.a = %u\n", fp->a); printf(" foo.b = %u\n", fp->b); printf(" foo.c = %u\n", fp->c); printf(" foo.d = %u\n", fp->d);}void * thr_fn1(void *arg){ // struct foo foo = {1, 2, 3, 4}; printfoo("thread 1:\n", &foo); pthread_exit((void *)&foo);}void * thr_fn2(void *arg){ printf("thread 2: ID is %u\n", pthread_self()); pthread_exit((void *)0);}int main(void){ int err; pthread_t tid1, tid2; struct foo *fp; err = pthread_create(&tid1, NULL, thr_fn1, NULL); if (err != 0) err_quit("can't create thread 1: %s\n", strerror(err)); err = pthread_join(tid1, (void *)&fp); if (err != 0) err_quit("can't join with thread 1: %s\n", strerror(err)); sleep(1); printf("parent starting second thread\n"); err = pthread_create(&tid2, NULL, thr_fn2, NULL); if (err != 0) err_quit("can't create thread 2: %s\n", strerror(err)); sleep(1); printfoo("parent:\n", fp); exit(0);}
运行结果:
wangye@wangye:~$ ./a.out
thread 1:
structure at 0x804a20c
foo.a = 1
foo.b = 2
foo.c = 3
foo.d = 4
parent starting second thread
thread 2: ID is 3076119408
parent:
structure at 0x804a20c
foo.a = 1
foo.b = 2
foo.c = 3
foo.d = 4
wangye@wangye:~$ ./a.out
thread 1:
structure at 0x804a20c
foo.a = 1
foo.b = 2
foo.c = 3
foo.d = 4
parent starting second thread
thread 2: ID is 3076119408
parent:
structure at 0x804a20c
foo.a = 1
foo.b = 2
foo.c = 3
foo.d = 4
这样就好了,那么动态分配了,我相信学过C 的人都会,下去自己体验一下吧!其实还有一种方法就是在每个线程里定义一个结构体变量也可以,但我们的主要目的是主线程希望得到子线程返回的值。所以在使用此函数时一定要注意!
- pthread_exit 参数使用
- pthread_exit ---- 不能使用局部变量作为参数返回
- 不正确的 pthread_exit参数
- pthread_exit()
- pthread_exit
- pthread_exit
- pthread_exit()
- pthread_exit()
- pthread_exit()
- pthread_exit
- pthread_exit()
- pthread_exit()
- pthread_join得到pthread_exit传出来的参数
- 关于pthread_exit(void *rval_ptr)使用void指针的问题
- pthread_exit简介
- pthread_join/pthread_exit
- pthread_exit手册
- pthread_join/pthread_exit
- POJ 1365 Prime Land(素因子分解)
- 纯手工js+Jquery打造的日历(根据一个网友自编的简单的js日历改造的)
- C++.Homework.C++Base.01
- Linux多线程与同步
- android 获取root修改系统时间
- pthread_exit 参数使用
- 二阶矩确定椭圆
- 提取汉字拼音首字母
- NTP服务器搭建
- 如何通过函数名获取虚函数的地址?
- OCP-1Z0-052-V8.02-70题
- 数据库事物
- Mongo数据库 安装 windiws
- Java里的堆(heap)栈(stack)和方法区(method)