linux c编程:线程退出
在线程创建的时候pthread_exit都是调用的固定参数,我们先来看下如果用自动变量作为pthread_exit的参数时出现的问题
typedef struct foo{
int a;
int b;
int c;
int d;
}foo;
void printinfo(const char *s,const struct foo *fp){
printf("%s",s);
printf("structure at 0x%lx\n",(unsigned long)fp);
printf("foo.a=%d\n",fp->a);
printf("foo.b=%d\n",fp->b);
printf("foo.c=%d\n",fp->c);
printf("foo.d=%d\n",fp->d);
}
void printids(const char *s){
pid_t pid;
pthread_t tid;
pid=getpid();
tid=pthread_self();
printf("%s pid %lu tid %lu (0x%lx)\n",s,(unsigned long)pid,(unsigned long)tid,(unsigned long)tid);
}
void *thr_fn2(void *arg){
printf("threaqd 2:ID is %lu\n",(unsigned long)pthread_self());
pthread_exit((void *)0);
}
void *thr_fn1(void *arg){
foo f={1,2,3,4};
printinfo("thread1:\n",&f);
pthread_exit((void *)&f);
}
int main()
{
pthread_t tid1,tid2;
foo *fp;
pthread_create(&tid1,NULL,thr_fn1,NULL);
pthread_join(tid1,(void *)&fp);
Sleep(1);
printf("parent starting create thread2:\n");
pthread_create(&tid2,NULL,thr_fn2,NULL);
Sleep(1);
printinfo("parent:\n",fp);
return 0;
}
在这个程序中,调用pthread_join(tid1,(void *)&fp)的时候会将返回码赋值给fp参数。然后再父进程中调用fp。
执行结果:可以看到当父进程中试图访问已退出的第一个线程传给它的结构时,内存不在有效,因此得到了SIGSEGV信号
Thread1:
Structure at 0x2bfff04
foo.a=1
foo.b=2
foo.c=3
foo.d=4
parent starting create thread2
thread 2 : ID is 3
segmentation fault(core dumped)
线程可以安排它退出时需要调用的函数,这样的函数称为线程清理处理程序。
void thread_cleanup_push(void (*rtn)(void *), void *arg);
void pthread_cleanup_pop(int execute)
rtn是调用的函数,arg是传入的参数。
void cleanup(void *arg){
printf("cleanup:%s\n",(char *)arg);
}
void *thr_fn2(void *arg){
printf("thread2 start\n");
pthread_cleanup_push(cleanup,"thread2 first handler");
pthread_cleanup_push(cleanup,"thread2 second handler");
printf("thread2 push complete\n");
if (arg)
pthread_exit((void *)2);
pthread_cleanup_pop(0);
pthread_cleanup_pop(0);
}
void *thr_fn1(void *arg){
printf("thread1 start\n");
pthread_cleanup_push(cleanup,"thread1 first handler");
pthread_cleanup_push(cleanup,"thread1 second handler");
printf("thread1 push complete\n");
if (arg)
return((void *)1);
pthread_cleanup_pop(0);
pthread_cleanup_pop(0);
}
int main()
{
pthread_t tid1,tid2;
void *tret;
pthread_create(&tid1,NULL,thr_fn1,(void *)1);
pthread_create(&tid2,NULL,thr_fn2,(void *)1);
pthread_join(tid1,&tret);
printf("thread 1 exit code %ld\n",(long)tret);
pthread_join(tid2,&tret);
printf("thread 2 exit code %ld\n",(long)tret);
return 0;
}
运行结果如下:两个线程都正确的自动启动和退出了,但是只有第二个线程的清理处理程序被调用了,如果线程是通过从它的启动历程中返回(return)而不是pthread_exit的话,它的清理程序就不会调用
最新文章
- windows和linux之间“/”, ";\\";的区别
- linux源码分析(四)-start_kernel-cgroup
- PHP之static静态变量详解(二)
- UVA 11210 中国麻将
- 【编程题目】n 个数字(0,1,…,n-1)形成一个圆圈,从数字 0 开始
- eclipse使用tips-Toggle Mark Occurrences 颜色更改
- Win10/UWP新特性系列—电池报告
- 设置 MyEclipse 默认打开文件方式
- 像素,分辨率,PPI(像素密度),BPP 扫盲
- GetClientRect
- 使用C#在VS中开发:未处理AccessViolationException “System.AccessViolationException”类型的未经处理的异常
- Eclipse MAT 安装及使用
- Beta(0/7)
- 关于java类加载机制的一些理解
- java 第三周作业
- 第三周博客总结 <;西北师范大学| 周安伟>;
- 当多线程并发遇到Actor
- kafka问题集锦
- 25条div+CSS编程提醒及小技巧整理
- 理解js中的函数调用和this
热门文章
- SpringMVC 文本文件下载的配置
- python调度框架APScheduler使用详解
- Cache和Buffer的区别(转载)
- JAVA学习第四十八课 — IO流(二):文件的复制 &;amp; 缓冲区1
- Mac 下Versions的 svn无法上传 .a 文件的问题
- Docker iptables failed: iptables -t nat -A DOCKER -p tcp
- C#常见的概念阐述
- SQL:OUTER JOIN使用方法具体解释
- Android实践--监測网络状态
- Linux下Java、Maven、Tomcat的安装