线程处理函数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);   
} 

补充一下: phtread_cleanup_push 与 phread_cleanup_pop要成对儿的出现,否则会报错!!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
`pthread_cleanup_push` 和 `pthread_cleanup_pop` 是 POSIX 线程库提供的两个函数,用于在线程退出时清理资源。 具体来说,当线程执行到 `pthread_cleanup_push` 函数时,它会将一个清理函数和一个参数压入线程的清理栈中。当线程退出时,无论是通过线程函数的 return 语句、pthread_exit 函数还是被取消,都会自动调用清理栈中的每个清理函数,并按照压入栈的顺序依次执行。 在多线程编程中,线程可能会因为各种原因(如出现异常)而异常终止,导致没有机会清理资源,从而造成资源泄漏或者其他问题。使用 `pthread_cleanup_push` 和 `pthread_cleanup_pop` 可以保证线程退出时一定会执行清理函数,避免这些问题。 下面是一个示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <pthread.h> void cleanup_handler(void *arg) { printf("cleanup: %s\n", (char *) arg); } void *thread_func(void *arg) { char *msg = (char *) arg; printf("thread: %s\n", msg); // 压入清理函数 pthread_cleanup_push(cleanup_handler, "thread is finished"); // 执行任务 sleep(5); // 弹出清理函数 pthread_cleanup_pop(1); pthread_exit(NULL); } int main() { pthread_t tid; int ret; ret = pthread_create(&tid, NULL, thread_func, "hello world"); if (ret != 0) { fprintf(stderr, "pthread_create error\n"); exit(EXIT_FAILURE); } // 等待线程退出 ret = pthread_join(tid, NULL); if (ret != 0) { fprintf(stderr, "pthread_join error\n"); exit(EXIT_FAILURE); } printf("main: thread is finished\n"); return 0; } ``` 在这个示例中,线程执行到 `pthread_cleanup_push` 函数时,它会将 `cleanup_handler` 函数和字符串 `"thread is finished"` 压入清理栈中。当线程执行完任务后,无论是正常退出还是被取消,都会自动调用 `cleanup_handler` 函数,并打印出 `"cleanup: thread is finished"` 的消息。 需要注意的是,如果在 `pthread_cleanup_push` 和 `pthread_cleanup_pop` 之间调用了 `pthread_exit`,那么清理函数也会被执行。但是如果在 `pthread_cleanup_push` 和 `pthread_cleanup_pop` 之间调用了 `longjmp`,那么清理函数就不会被执行。因此,不要在使用 `setjmp` 和 `longjmp` 的代码中使用 `pthread_cleanup_push` 和 `pthread_cleanup_pop`。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值