您的位置:首页 > 运维架构

pthread_cleanup_push/pop成对出现的意义

2014-03-22 21:41 330 查看
首先简单介绍一下这两条API
线程可以安排它退出时需要调用的函数,这样的函数称为线程清理处理程序,线程可以建立多个清理处理程序。处理程序记录在栈中,也就是说它们的执行顺序与它们注册时的顺序相反。pthread_cleanup_push来注册清理函数rtn,这个函数有一个参数arg。在以下三种情形之一发生时,注册的清理函数被执行:1)调用pthread_exit。2)作为对取消线程请求(pthread_cancel)的响应。3)以非0参数调用pthread_cleanup_pop。注意:1)如果线程只是由于简单的返回而终止的,则清除函数不会被调用。2)如果pthread_cleanup_pop被传递0参数,则清除函数不会被调用,但是会清除处于栈顶的清理函数以下需要注意的1,push与pop一定是成对出现的,其实push中包含"{"而pop中包含"}",少一个不行。2,push可以有多个,同样的pop也要对应的数量,遵循"先进后出原则"。但是下面的代码经常会出现
void child(void *t)
{
pthread_cleanup_push(pthread_mutex_unlock,&mutex);
pthread_mutex_lock(&mutex);
..............
pthread_mutex_unlock(&mutex);
pthread_cleanup_pop(0);
}
可能大家会觉得奇怪,既然pthread_cleanup_pop(0); 的参数是0,pthread_mutex_unlock不会被调用,那么为什么还需要写pthread_cleanup_pop可能大家会答因为push和pop是宏并且被设计成"{"和“}”,所以它们一定要一对出现。我想说的是为什么它们被设计成一对,这样子意义是什么?而且很多时候出现pthread_cleanup_pop(0),感觉这样子带来很多没有必要的麻烦(多写这个函数)。答案是,它们成对出现时有意义,我先看下面的例子
void child(void *t)
{
pthread_cleanup_push(pthread_mutex_unlock,&mutex);
pthread_mutex_lock(&mutex);
..............
pthread_mutex_unlock(&mutex);
pthread_cleanup_pop(0);
// something unimportant code
do_something1();
do_something2();
}
在do_something1()后面的代码,无论线程怎么退出,都没有thread_cleanup_handler被调用,所以push和pop成对出现的意义就是对thread_cleanup_handler作用域限定一定范围的代码,这样子就可以根据不同代码段注册不同的thread_cleanup_handler,当该代码段运行结束,对应的thread_cleanup_handler也被pop出来,也就是失效了。比如下面的例子
void child(void *t)
{
pthread_cleanup_push(pthread_dosomething1_handler,&mutex);
dosomething1();
pthread_cleanup_pop(0);
pthread_cleanup_push(pthread_dosomething2_handler,&mutex);
dosomething2();
pthread_cleanup_pop(0);
pthread_cleanup_push(pthread_dosomething2_handler,&mutex);
dosomething2();
pthread_cleanup_pop(0);
}

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: