pthread_cleanup

 首先你必须知道pthread_cleanup_push与pthread_cleanup_pop的目的(作用)是什么。

比如thread1:
执行pthread_mutex_lock(&mutex);
//一些会阻塞程序运行的调用,比如套接字的accept,等待客户连接
sock = accept(......);            //这里是随便找的一个可以阻塞的接口
pthread_mutex_unlock(&mutex);


这个例子中,如果线程1执行accept时,线程会阻塞(也就是等在那里,有客户端连接的时候才返回,或则出现其他故障),线程等待中......
这时候线程2发现线程1等了很久,不赖烦了,他想关掉线程1,于是调用pthread_cancel()或者类似函数,请求线程1立即退出。
这时候线程1仍然在accept等待中,当它收到线程2的cancel信号后,就会从accept中退出,然后终止线程,注意这个时候线程1还没有执行:
pthread_mutex_unlock(&mutex);
也就是说锁资源没有释放,这回造成其他线程的死锁问题。

所以必须在线程接收到cancel后用一种方法来保证异常退出(也就是线程没达到终点)时可以做清理工作(主要是解锁方面),pthread_cleanup_push与pthread_cleanup_pop就是这样的。
pthread_cleanup_push(some_clean_func,...)
pthread_mutex_lock(&mutex);

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
void *clean(void *arg)
{
    printf("cleanup :%s \n",(char *)arg);
    return (void *)0;
}
void *thr_fn1(void *arg)
{
    printf("thread 1 start \n");
    pthread_cleanup_push( (void*)clean,"thread 1 first handler");
    pthread_cleanup_push( (void*)clean,"thread 1 second hadler");
    printf("thread 1 push complete \n");
    if(arg)
    {
        printf("thread 1 return\n");
        return((void *)1);
    }
    pthread_cleanup_pop(0);
    pthread_cleanup_pop(0);
// pthread_cleanup_pop(1); // pthread_cleanup_pop(1);
return (void *)1; } void *thr_fn2(void *arg) { printf("thread 2 start \n"); pthread_cleanup_push( (void*)clean,"thread 2 first handler"); pthread_cleanup_push( (void*)clean,"thread 2 second handler"); printf("thread 2 push complete \n"); if(arg) { printf("thread 2 return\n"); pthread_exit((void *)2); } pthread_cleanup_pop(0); pthread_cleanup_pop(0);
// pthread_cleanup_pop(1); // pthread_cleanup_pop(1); pthread_exit((
void *)2); } int main(void) { int err; pthread_t tid1,tid2; void *tret; // err=pthread_create(&tid1,NULL,thr_fn1,(void *)1); err=pthread_create(&tid1,NULL,thr_fn1,(void *)0); if(err!=0) { printf("error .... \n"); return -1; }

//  err=pthread_create(&tid1,NULL,thr_fn1,(void *)1);
    err=pthread_create(&tid2,NULL,thr_fn2,(void *)0);
if(err!=0) { printf("error .... \n"); return -1; } err=pthread_join(tid1,&tret); if(err!=0) { printf("error .... \n"); return -1; } printf("thread 1 exit code %ld \n",(long)tret); err=pthread_join(tid2,&tret); if(err!=0) { printf("error .... "); return -1; } printf("thread 2 exit code %ld \n",(long)tret); return 1; }

 

posted @ 2015-12-31 19:34  牧 天  阅读(342)  评论(0)    收藏  举报