pthread_cleanup_push()/pop()线程终止清理
2016-02-01 22:07
274 查看
pthread_cleanup_push()和pthread_cleanup_pop()
线程为了访问临界共享资源而为其加上锁,但在访问过程中该线程被外界取消,或者发生了中断,则该临界资源将永远处于锁定状态得不到释放。外界取消操作是不可预见的,因此的确需要一个机制来简化用于资源释放的编程。在POSIX线程API中提供了一个
pthread_cleanup_push()/pthread_cleanup_pop()函数对用于自动释放资源–从
pthread_cleanup_push()的调用点到
pthread_cleanup_pop()之间的程序段中的终止动作都将执行
pthread_cleanup_push()所指定的清理函数。
API定义如下:
void pthread_cleanup_push(void (*routine) (void *), void *arg) void pthread_cleanup_pop(int execute)
pthread_cleanup_push()/pthread_cleanup_pop()采用先入后出的栈结构管理
void routine(void *arg)函数在调用
pthread_cleanup_push()时压入清理函数栈,多次对
pthread_cleanup_push()的调用将在清理函数栈中形成一个函数链,在执行该函数链时按照压栈的相反顺序弹出。
execute参数表示执行到
pthread_cleanup_pop()时是否在弹出清理函数的同时执行该函数,为0表示不执行,非0为执行;这个参数并不影响异常终止时清理函数的执行。
pthread_cleanup_push()/pop()以宏方式实现
这是
pthread.h中的宏定义:
#define pthread_cleanup_push(routine,arg) \ { struct _pthread_cleanup_buffer _buffer; \ _pthread_cleanup_push (&_buffer, (routine), (arg)); #define pthread_cleanup_pop(execute) \ _pthread_cleanup_pop (&_buffer, (execute)); }
可见,
pthread_cleanup_push()带有一个”{“,而pthread_cleanup_pop()带有一个”}”,因此这两个函数必须成对出现,且必须位于程序的同一级别的代码段中才能通过编译。
pthread_cleanup_pop的参数
execute如果为非0值,则按栈的顺序注销掉一个原来注册的清理函数,并执行该函数;
当
pthread_cleanup_pop()函数的参数为0时,仅仅在线程调用
pthread_exit函数或者其它线程对本线程调用
pthread_cancel函数时,才在弹出“清理函数”的同时执行该“清理函数”。
程序实例
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> /*释放内存*/ void free_mem(void *arg) { free(arg); printf("clean up the memory!\n"); } /*线程函数*/ void *my_fun(void *arg) { char *p = (char*)malloc(10);/*线程函数分配了内存*/ pthread_cleanup_push(free_mem, p); int i = 0; for(i = 0;i<10;i++){ printf("this is myfun\n"); sleep(1); } pthread_exit((void*)3);/*退出当前线程*/ pthread_cleanup_pop(0); } int main() { pthread_t ptid; pthread_create(&ptid, NULL, my_fun, NULL); int i; for(i = 1; i < 5; i++ ){ printf("hey naive\n"); sleep(1); if(i % 3 == 0){ pthread_cancel(ptid); //i=3时将导致线程函数直接退出,将不会释放my_fun中的malloc的内存 //使用pthread_cleanup_push/pop释放 } } int ret; pthread_join(ptid, (void**)&ret); printf("return value is : %d\n", ret); return 0; }
程序执行结果:
hey naive this is myfun hey naive this is myfun hey naive this is myfun hey naive clean up the memory! return value is : -1
若不加
pthread_cleanup_push/pop释放,将不会打印
clean up the memory!即对线程函数
malloc的内存未完成清理。
相关文章推荐
- win7旗舰版安装office2007后打开文件提示找不到proplusww.msi
- linux基础指令(一)arch
- 学习笔记1 Supervised Learning and Optimization 之 Linear and Logistic Regression
- Operations-tools
- Linux--字符设备驱动结构框图
- $scope
- 初探linux子系统集之timer子系统(一)
- 初探linux子系统集之timer子系统(一)
- 初探linux子系统集之timer子系统(二)
- 初探linux子系统集之timer子系统(二)
- VS2010 下安装 openssl
- linux下安装中文检索软件 sphinx/coreseek
- Hadoop资源可视化、提高吞吐量的调度工具Pepperdata介绍
- Docker(二)
- [转]Eclipse中的Web项目自动部署到Tomcat
- linux命令学习之(cat)
- opencv(7)
- linux 命令
- codeforces 621B Wet Shark and Bishops
- Linux虚拟化之XenServer的安装与配置管理