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

linux c编程:线程退出的更多相关文章

  1. Linux 多线程编程--线程退出

    今天分析项目中进程中虚存一直增长问题,运行10个小时虚存涨到121G ,RSS占用为16G 非常恐怖. Valgrind测试无内存泄漏. 内存32G 64bit系统信息如下: Linux线程使用方式是 ...

  2. Linux多线程编程——线程的创建与退出

    POSIX线程标准:该标准定义了创建和操纵线程的一整套API.在类Unix操作系统(Unix.Linux.Mac OS X等)中,都使用Pthreads作为操作系统的线程.Windows操作系统也有其 ...

  3. Linux多任务编程——线程

    线程基础 △ 由于进程的地址空间是私有的,因此在进行上下文切换时,系统开销比较大 △ 在同一个进程中创建的线程共享该进程的地址空间 △ 通常线程值得是共享相同地址空间的多个任务 △ 每个线程的私有这些 ...

  4. Linux系统编程——线程私有数据

    在多线程程序中.常常要用全局变量来实现多个函数间的数据共享.因为数据空间是共享的,因此全局变量也为全部线程共同拥有. 測试代码例如以下: #include <stdio.h> #inclu ...

  5. linux系统编程--线程

    安装线程man page,命令:sudo apt-get install manpages-posix-dev 线程概念 什么是线程 LWP:light weight process 轻量级的进程,本 ...

  6. linux系统编程--线程同步

    同步概念 所谓同步,即同时起步,协调一致.不同的对象,对“同步”的理解方式略有不同. 如,设备同步,是指在两个设备之间规定一个共同的时间参考: 数据库同步,是指让两个或多个数据库内容保持一致,或者按需 ...

  7. Linux系统编程 —线程同步概念

    同步概念 同步,指对在一个系统中所发生的事件之间进行协调,在时间上出现一致性与统一化的现象. 但是,对于不同行业,对于同步的理解略有不同.比如:设备同步,是指在两个设备之间规定一个共同的时间参考:数据 ...

  8. Linux——网络编程线程池机制

    #include <stdlib.h>#include <pthread.h>#include <unistd.h>#include <assert.h> ...

  9. LInux多线程编程----线程特定数据的处理函数

    1.pthread_key_t和pthread_key_create() 线程中特有的线程存储, Thread Specific Data .线程存储有什么用了?他是什么意思了?大家都知道,在多线程程 ...

  10. Linux系统编程 —线程属性

    在之前的章节中,我们在调用pthread_create函数创建线程时,第二个参数(即线程属性)都是设为NULL,即使用默认属性.一般情况下,使用默认属性已经可以解决我们开发过程中的大多数问题. 但是, ...

随机推荐

  1. 【前端开发】 5分钟创建 Mock Server

    http://blog.csdn.net/wxqee/article/details/50165581 NOTIFY 官网文档现在已经很简约.很强大了,建议直接点击这里: Getting Starte ...

  2. java.lang.IllegalArgumentException: Wrong state classs

    java.lang.IllegalArgumentException: Wrong state class, expecting View State but received class cn.et ...

  3. 【Java】各种软件安装与环境配置的失败

    又来到了java的世界,看了一段时间的视频.感觉太空虚,便从网上找到一个教程.想做几个demo试试,少不了的前期准备:Java开发环境配置,Eclipse JSP/Servlet 环境搭建等.     ...

  4. 使用 JavaScript开发的跨平台音乐、书籍播放器

    代码地址如下:http://www.demodashi.com/demo/12542.html 演示效果 歌曲推荐界面 歌手搜索界面 歌词预览界面 书籍推荐界面 代码实现过程 首页代码: 'use s ...

  5. 网络爬虫与搜索引擎优化(SEO)

    一.网络爬虫 网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本.另外一些不常使用的名字还有蚂蚁.自动索引. ...

  6. [linux]iostat命令详解-监视系统输入输出设备和CPU的使用情况

    部分转载https://blog.csdn.net/sunansheng/article/details/51942281 iostat命令被用于监视系统输入输出设备和CPU的使用情况.它的特点是汇报 ...

  7. web-小知识点(随记)

    1.position:fixed:窗口定位的时候(在刷新页面时若未出现.得稍等一会的话,就直接把需要定位的内容写在<html>标签的首部.这样页面加载html的时候首先加载fixed定位的 ...

  8. 关于javaSocket中 Software caused connection abort: recv failed问题

    在学习Socket中今天突然遇到了以下这种问题 原来是网路连接出了问题,由于我測试的是远程连接所以是在学校的局域网下,结果非常不稳定,開始还以为怎么了一会连上了一会又出现故障然后把IP地址改为本机的1 ...

  9. 让 webpack 加载 Source Map

    在浏览器中运行的 JavaScript 代码都是编译器输出的代码,这些代码的可读性很差.如果在开发过程中遇到一个不知道原因的 Bug,则你可能需要通过断点调试去找出问题. 在编译器输出的代码上进行断点 ...

  10. docker教程之从一头雾水到不一头雾水(2)

    书接上文:docker教程之从一头雾水到不一头雾水(1) 运行镜像 先查看下本地有哪些镜像 [root@ichz ~]# docker images REPOSITORY TAG IMAGE ID C ...