pthread_cleanup_push和pthread_clean_pop详解
时间: 2023-10-19 21:11:21 浏览: 78
pthread_cond_wait() 用法深入分析
`pthread_cleanup_push` 和 `pthread_cleanup_pop` 是 pthread 库提供的一对宏,用于在线程退出时执行清理函数。这对宏应该总是成对出现,其中 `pthread_cleanup_push` 用于注册清理函数,而 `pthread_cleanup_pop` 用于撤销注册的清理函数。
`pthread_cleanup_push` 的原型如下:
```C
void pthread_cleanup_push(void (*routine)(void*), void *arg);
```
其中 `routine` 是将要执行的清理函数, `arg` 是传递给清理函数的参数。该函数的作用是将清理函数和参数压入线程的 cleanup 栈中。
`pthread_cleanup_pop` 的原型如下:
```C
void pthread_cleanup_pop(int execute);
```
该函数的作用是从 cleanup 栈中弹出一个清理函数,如果 `execute` 参数为非零值,则会执行该清理函数;否则,不执行该清理函数。
下面是一个简单的示例程序,它演示了如何使用 `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 = "thread exit";
pthread_cleanup_push(cleanup_handler, msg);
printf("thread is running\n");
// do some work here
// ...
pthread_exit(NULL);
pthread_cleanup_pop(0);
}
int main()
{
pthread_t tid;
int ret;
ret = pthread_create(&tid, NULL, thread_func, NULL);
if (ret != 0) {
perror("pthread_create");
exit(EXIT_FAILURE);
}
// wait for thread to exit
ret = pthread_join(tid, NULL);
if (ret != 0) {
perror("pthread_join");
exit(EXIT_FAILURE);
}
printf("main thread exit\n");
return 0;
}
```
在这个示例程序中,创建了一个新的线程,并在其中注册了一个清理函数 `cleanup_handler`。在线程执行期间,如果线程调用了 `pthread_exit` 函数,那么该线程就会退出,并在退出之前先执行注册的清理函数。最后,在主线程中使用 `pthread_join` 等待子线程退出。当子线程退出时,它会先执行注册的清理函数,然后再退出。
需要注意的是,每个线程都有自己的 cleanup 栈。当线程退出时,会依次执行 cleanup 栈中的清理函数。如果某个清理函数调用了 `pthread_exit` 或者抛出了异常,那么后续的清理函数就不会执行了。因此,如果需要确保所有的清理函数都被执行,就需要在每个清理函数中进行错误处理,并确保不会终止线程的执行。
阅读全文