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

2011-07-01 17:13 4426人阅读 评论(0) 收藏 举报

线程可以安排它退出时需要调用的函数,这样的函数称为线程清理处理程序,线程可以建立多个清理处理程序。处理程序记录在栈中,也就是说它们的执行顺序与它们注册时的顺序相反。

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的更多相关文章

  1. ZT pthread_cleanup_push()/pthread_cleanup_pop()的详解

    pthread_cleanup_push()/pthread_cleanup_pop()的详解 分类: Linux 2010-09-28 16:02 1271人阅读 评论(1) 收藏 举报 async ...

  2. pthread_cleanup_push()/pthread_cleanup_pop()的详解

    一般来说,Posix的线程终止有两种情况:正常终止和非正常终止.线程主动调用pthread_exit()或者从线程函数中return都将使线程正常退出,这是可预见的退出方式:非正常终止是线程在其他线程 ...

  3. 对线程等待函数pthread_join二级指针参数分析

    分析之前先搞明白,这个二级指针其实在函数内部是承接了上个线程的返回值. 看man手册,发现返回值是个普通指针.人家用二级指针来承接,可能准备干大事.这个可以自己搜索一下.原因嘛,二级指针是保存了这个地 ...

  4. POSIX多线程——基本线程管理函数介绍

    POSIX基本的几个线程管理函数见下表: ------------------------------------------------------------------------------- ...

  5. ZT 线程的分离状态 2012-08-16 17:00:59

    线程的分离状态 2012-08-16 17:00:59 分类: LINUX 其实在写上一篇日志的时候,由于我把创建线程的返回值的判断条件写错了,程序每次运行的时候都是显示创建线程失败,我就百度了一下, ...

  6. WIN内核线程池函数

    线程池 (本章节中样例都是用 VS2010 编译调试的) 线程池编写必须在 Windows Vista 操作系统(以及以上版本号的操作系统)下,且 C++ 编译器版本号至少是 VS2008 线程池的功 ...

  7. 线程的函数中调用MFC对话框类的变量

    线程的函数中调用MFC对话框类的变量多线程传输文件的对话框 现在想要在对话框上添加一个进度条 为进度条映射变量m_progress这就需要在传输一段文件后就更新m_progress的值使进度条前进 也 ...

  8. POSIX 线程清理函数

    POSIX 多线程的 cleanup 函数 控制清理函数的函数有两个,一个是 pthread_cleanup_push(), 用来把清理函数压入栈中,另一个是 pthread_cleanup_pop( ...

  9. Linux线程基础函数

    1. 线程标识: (1) 比较两个线程ID: #include <pthread.h> int pthread_equal(pthread_t tid1, pthread_t tid2); ...

随机推荐

  1. Callable和Future详解

    Java程序员必须掌握的线程知识-Callable和Future Callable和Future出现的原因 创建线程的两种方式:继承Thread类和实现Runnable接口 这两种方式都有一种缺陷,执 ...

  2. GroupBox 分组框控件

    GroupBox 控件是由System.Windows.Forms.GroupBox类提供的,作用是为其他控件提供可识别的分组.   可在同一页面,实现多个单选的RadioButton   通常,使用 ...

  3. SVG 旋转图形实例

    本实例展示如何在SVG中画出一个正方形并使之旋转.运行结果如下图所示: 在文本框中输入时间间隔,单位是毫秒.点击Start按钮,蓝色方块就会开始转动,每个时间间隔变化一度.变换的角度在下面的Angle ...

  4. Winform学习之随笔一:Log4net

    前提题要:因为我最近负责的Winform项目,好多都用到了这个log4net的日志功能,开发程序对数据一般都要求做到雁过留痕,所以日志对于我们程序员是不可或缺.因此我把对log4net的使用做一个记录 ...

  5. layui使用 ——父,子页面传值

    页面传值是非常常用的,layui自带弹窗功能,但是内置使用的是location.href 暂时没找到方法条件请求头,所以在后台需要放开拦截器, layer.open({ type : 2, title ...

  6. 撩课-Web大前端每天5道面试题-Day3

    1. javascript的typeof返回哪些数据类型? 答案: undefined string boolean number symbol(ES6) Object Function 2. 列举3 ...

  7. Java 泛型的使用

    一.泛型的简介1.为什么要使用泛型? 一般使用在集合上,比如现在把一个字符串类型的值放入到集合里面,这个时候,这个值放到集合之后,失去本身的类型,只能是object类型.这时,如果想要对这个值进行类型 ...

  8. JS判断两个数是否能除尽

    function judgeDivisor(m, n) { var num = {}; var i = 0; var x = parseInt(m / n); m = m % n; var resul ...

  9. UOJ#316. 【NOI2017】泳池

    传送门 一道 \(DP\) 好题 设 \(q\) 为一个块合法的概率 套路一恰好为 \(k\) 的概率不好算,算小于等于 \(k\) 的减去小于等于 \(k-1\) 的 那么设 \(f_i\) 表示宽 ...

  10. HEOI2017 游记

    你若安好,便是晴天. …… 人就像命运下的蝼蚁,谁也无法操控自己的人生. ——阮行止 …… Day 0 中午就要出发了,上午教练还搞了一场欢乐信心赛,然而还是挂惨了.T3是bzoj的原题,但是当时写的 ...