在线程创建的时候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的话,它的清理程序就不会调用

最新文章

  1. windows和linux之间“/”, "\\"的区别
  2. linux源码分析(四)-start_kernel-cgroup
  3. PHP之static静态变量详解(二)
  4. UVA 11210 中国麻将
  5. 【编程题目】n 个数字(0,1,…,n-1)形成一个圆圈,从数字 0 开始
  6. eclipse使用tips-Toggle Mark Occurrences 颜色更改
  7. Win10/UWP新特性系列—电池报告
  8. 设置 MyEclipse 默认打开文件方式
  9. 像素,分辨率,PPI(像素密度),BPP 扫盲
  10. GetClientRect
  11. 使用C#在VS中开发:未处理AccessViolationException “System.AccessViolationException”类型的未经处理的异常
  12. Eclipse MAT 安装及使用
  13. Beta(0/7)
  14. 关于java类加载机制的一些理解
  15. java 第三周作业
  16. 第三周博客总结 <西北师范大学| 周安伟>
  17. 当多线程并发遇到Actor
  18. kafka问题集锦
  19. 25条div+CSS编程提醒及小技巧整理
  20. 理解js中的函数调用和this

热门文章

  1. SpringMVC 文本文件下载的配置
  2. python调度框架APScheduler使用详解
  3. Cache和Buffer的区别(转载)
  4. JAVA学习第四十八课 — IO流(二):文件的复制 & 缓冲区1
  5. Mac 下Versions的 svn无法上传 .a 文件的问题
  6. Docker iptables failed: iptables -t nat -A DOCKER -p tcp
  7. C#常见的概念阐述
  8. SQL:OUTER JOIN使用方法具体解释
  9. Android实践--监測网络状态
  10. Linux下Java、Maven、Tomcat的安装