ZT 线程处理函数pthread_cleanup_push / pthread_cleanup_pop
http://bbs.csdn.net/topics/390688105
2)创建了线程,但是线程退出时没有线程调用pthread_join()
线程资源没有回收,如果持续创建线程,到一定数量后将不能再创建!
可以在创建的线程中使用pthread_detach(pthread_self()),主线程就可以不调用pthread_join()
1)只有pthread_cleanup_push() 直到进程退出都 没有调用pthead_cleanup_pop()
pthread_cleanup_push压栈的函数在3种情况下会调用, 该线程调用pthread_exit()、其它线程调用pthread_cancel(pid)、该线程调用pthread_cleanup_pop(int execute)
不属于以上三种情况时,如果进程不退出,估计就是有压栈信息的内存泄露
线程处理函数pthread_cleanup_push / pthread_cleanup_pop
线程可以安排它退出时需要调用的函数,这样的函数称为线程清理处理程序,线程可以建立多个清理处理程序。处理程序记录在栈中,也就是说它们的执行顺序与它们注册时的顺序相反。
pthread_cleanup_push来注册清理函数rtn,这个函数有一个参数arg。在以下三种情形之一发生时,注册的清理函数被执行:
1)调用pthread_exit。
2)作为对取消线程请求(pthread_cancel)的响应。
3)以非0参数调用pthread_cleanup_pop。
注意:
1)如果线程只是由于简单的返回而终止的,则清除函数不会被调用。
2)如果pthread_cleanup_pop被传递0参数,则清除函数不会被调用,但是会清除处于栈顶的清理函数。
|
名称: |
pthread_cleanup_push / pthread_cleanup_pop |
|
功能: |
线程清理处理程序 |
|
头文件: |
#include <pthread.h> |
|
函数原形: |
void pthread_cleanup_push(void (*rtn)(void *),void *arg); void pthread_cleanup_pop(int execute); |
|
参数: |
rtn 处理程序入口地址 arg 传递给处理函数的参数 |
|
返回值: |
无 |
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
void cleanup(void *arg){
printf("cleanup: %s/n",(char *)arg);
}
void *thr_fn1(void *arg){
printf("thread 1 start/n");
pthread_cleanup_push(cleanup,"thread 1 first handler");
pthread_cleanup_push(cleanup,"thread 1 second handler");
printf("thread 1 push complete/n");
if(arg)
return ((void *)1);
pthread_cleanup_pop(1);
pthread_cleanup_pop(1);
return ((void *)1);
}
void *thr_fn2(void *arg){
printf("thread 2 start/n");
pthread_cleanup_push(cleanup,"thread 2 first handler");
pthread_cleanup_push(cleanup,"thread 2 second handler");
printf("thread 2 push complete/n");
if(arg){
pthread_exit((void *)2);
}
pthread_cleanup_pop(0); //取消第一个线程处理程序
pthread_cleanup_pop(0); //取消第二个线程处理程序
pthread_exit((void *) 2);
}
int main(void){
int err;
pthread_t tid1,tid2;
void *tret;
err = pthread_create(&tid1,NULL,thr_fn1,(void *)1);
if( err != 0){
fprintf(stderr,"create thread1 failed: %s",strerror(err));
exit(1);
}
err = pthread_create(&tid2,NULL,thr_fn2,(void *)2);
if(err != 0){
fprintf(stderr,"create thread 2 failed: %s",strerror(err));
exit(1);
}
err = pthread_join(tid1,&tret);
if(err != 0){
fprintf(stderr,"thread1 join failed: %s",strerror(err));
exit(1);
}
printf("thread 1 exit code %d/n",(int)tret);
err = pthread_join(tid2,&tret);
if(err != 0){
fprintf(stderr,"thread2 join failed: %s",strerror(err));
exit(1);
}
printf("thread 2 exit code %d/n",(int) tret);
exit(0);
}
ZT 线程处理函数pthread_cleanup_push / pthread_cleanup_pop的更多相关文章
- ZT pthread_cleanup_push()/pthread_cleanup_pop()的详解
pthread_cleanup_push()/pthread_cleanup_pop()的详解 分类: Linux 2010-09-28 16:02 1271人阅读 评论(1) 收藏 举报 async ...
- pthread_cleanup_push()/pthread_cleanup_pop()的详解
一般来说,Posix的线程终止有两种情况:正常终止和非正常终止.线程主动调用pthread_exit()或者从线程函数中return都将使线程正常退出,这是可预见的退出方式:非正常终止是线程在其他线程 ...
- 对线程等待函数pthread_join二级指针参数分析
分析之前先搞明白,这个二级指针其实在函数内部是承接了上个线程的返回值. 看man手册,发现返回值是个普通指针.人家用二级指针来承接,可能准备干大事.这个可以自己搜索一下.原因嘛,二级指针是保存了这个地 ...
- POSIX多线程——基本线程管理函数介绍
POSIX基本的几个线程管理函数见下表: ------------------------------------------------------------------------------- ...
- ZT 线程的分离状态 2012-08-16 17:00:59
线程的分离状态 2012-08-16 17:00:59 分类: LINUX 其实在写上一篇日志的时候,由于我把创建线程的返回值的判断条件写错了,程序每次运行的时候都是显示创建线程失败,我就百度了一下, ...
- WIN内核线程池函数
线程池 (本章节中样例都是用 VS2010 编译调试的) 线程池编写必须在 Windows Vista 操作系统(以及以上版本号的操作系统)下,且 C++ 编译器版本号至少是 VS2008 线程池的功 ...
- 线程的函数中调用MFC对话框类的变量
线程的函数中调用MFC对话框类的变量多线程传输文件的对话框 现在想要在对话框上添加一个进度条 为进度条映射变量m_progress这就需要在传输一段文件后就更新m_progress的值使进度条前进 也 ...
- POSIX 线程清理函数
POSIX 多线程的 cleanup 函数 控制清理函数的函数有两个,一个是 pthread_cleanup_push(), 用来把清理函数压入栈中,另一个是 pthread_cleanup_pop( ...
- Linux线程基础函数
1. 线程标识: (1) 比较两个线程ID: #include <pthread.h> int pthread_equal(pthread_t tid1, pthread_t tid2); ...
随机推荐
- I/O的整体介绍
java的i/o操作类在包java.io下,大概可以分成如下四组: 基于字节操作的 I/O 接口:InputStream 和 OutputStream 基于字符操作的 I/O 接口:Writer 和 ...
- poj 1222EXTENDED LIGHTS OUT
高斯消元的题本质思想一样. 学习网址:http://www.cnblogs.com/rainydays/archive/2011/08/31/2160748.html #include <ios ...
- 记一次接口调用耗时服务端PHP-FPM配置调优
最近测试人员不时有反馈,APP首页打开会出现除了基本的页面布局,需要展示数据的地方都是空白. 想着最近首页接口有过调整,新增数据.会不会是接口改动导致的?? 但APP首页接口都是读取redis的,应该 ...
- ios手势识别代理
之前做优质派时写了个仿网易新闻导航的第三方,由于当时做项目时这个主控制器就是RootViewController,虽然用的是ScrollView但也没考虑到导航栏的手势返回的问题 ,现在做小区宝3.0 ...
- [转]OData – the best way to REST–实例讲解ASP.NET WebAPI OData (V4) Service & Client
本文转自:http://www.cnblogs.com/bluedoctor/p/4384659.html 一.概念介绍 1.1,什么是OData? 还是看OData官网的简单说明: An open ...
- php 数组任意位置插入值
array_splice() $arr = array('A', 'B', 'C'); $arr2 = 'abc';$t = array_splice($arr, 1, 0, $arr2); prin ...
- 【转】Windows 平台下 Go 语言的安装和环境变量设置
1. Go 语言 SDK 安装包下载和安装 最新稳定版 1.5.3 安装包 go1.5.3.windows-amd64.msi下载地址 https://golang.org/dl/,大小约 69 MB ...
- 撩课-Java每天10道面试题第1天
1.简述JDK.JRE.JVM? 一.JDK JDK(Java Development Kit) 是整个JAVA的核心, 包括了Java运行环境(Java Runtime Envirnment), 一 ...
- java设计模式-----3、抽象工厂模式
抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态.抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式.抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创 ...
- Oracle数据库基本操作 (六) —— 数据的导出与导入
一.cmd 下登录oracle数据库下的指定用户 方式一:命令行明文连接登录 打开cmd,输入:sqlplus/nolog 输入:conn username/passworld@数据库实例名 方式二: ...