飞凌嵌入式ElfBoard-线程之线程清理
类似于atexit()函数注册进程终止处理函数,当进程调用 exit()退出时就会执行进程终止处理函数;当线程退出时也会调用线程清理的相关函数。
在多线程编程中,当一个线程退出时,可以使用 pthread_cleanup_push()和 pthread_cleanup_pop()来注册和弹出清理函数。这些清理函数在线程正常结束或响应取消请求时自动调用,用于释放资源或执行特定的清理操作。
1.pthread_cleanup_push
可以将一个清理函数 routine 入栈。当线程退出或被取消时,所有入栈的清理函数会按照后进先出的顺序执行,确保资源的有序释放。
1)头文件
#include <pthread.h>
2)函数原型
void pthread_cleanup_push(void (*routine)(void *),void *arg);
3)参数
routine:指向要在线程退出时执行的清理函数的指针。清理函数应该接收一个 void * 类型的参数。
arg:传递给清理函数 routine 的参数。
4)返回值
无。
2.pthread_cleanup_pop
可以将 pthread_cleanup_push 入栈的清理函数出栈。如果 execute 为非零值,则会立即执行该清理函数;如果 execute 为零,则仅从栈中移除,不执行清理函数。
1)头文件
#include <pthread.h>
2)函数原型
void pthread_cleanup_pop(int execute);
3)参数
execute:为非零值时会立即执行上一个 pthread_cleanup_push 注册的清理函数;如果为零,则不会调用清理函数。
4)返回值
无
5)注意情况
pthread_cleanup_push 和 pthread_cleanup_pop 必须在同一个函数作用域内配对使用,否则会导致编译错误。
pthread_cleanup_pop(1) 会立即执行清理函数,而 pthread_cleanup_pop(0) 仅从栈中移除注册的清理函数而不执行。
如果线程在 pthread_cleanup_pop 之前因取消或调用 pthread_exit 退出,清理函数会自动执行。
6)示例:线程清理函数的使用
#include <stdio.h> #include <pthread.h> #include <unistd.h> void cleanup(void *arg) { printf("Cleaning up: %s\n", (char *)arg); } void *thread_func(void *arg) { pthread_cleanup_push(cleanup, "Resource 1"); pthread_cleanup_push(cleanup, "Resource 2"); printf("Thread is running\n"); // 模拟一些操作或阻塞 sleep(2); // 出栈但不执行第一个清理函数 pthread_cleanup_pop(0); // 出栈并立即执行第二个清理函数 pthread_cleanup_pop(1); return NULL; } int main() { pthread_t thread; pthread_create(&thread, NULL, thread_func, NULL); pthread_join(thread, NULL); return 0; } |
7)运行结果
Thread is running Cleaning up: Resource 1 |
8)代码解析
pthread_cleanup_pop(0) 仅移除了 Resource 2 的清理函数而不执行,而 pthread_cleanup_pop(1) 则执行了 Resource 1 的清理函数。在此过程中,线程的清理函数可以根据条件执行或仅从清理栈中移除。
