"); //-->
在 Linux 多线程编程中,线程终止时可以执行特定的清理操作,通过注册线程清理函数(thread cleanup handler)来实现。
这类似于使用 atexit() 注册进程终止处理函数。
线程清理函数用于在线程退出时执行一些资源释放或清理工作,例如关闭文件描述符、释放内存等。
不同于进程,线程可以注册多个清理函数,这些清理函数以栈的形式管理,栈是一种先进后出的数据结构。
因此,清理函数的执行顺序与注册顺序相反。
在 Linux 中,使用 pthread_cleanup_push() 和 pthread_cleanup_pop() 函数分别向线程的清理函数栈添加和移除清理函数。
其原型如下:
void pthread_cleanup_push(void (*routine)(void *); void *arg);void pthread_cleanup_pop(int execute);
参数说明:
pthread_cleanup_push():用于将清理函数推入栈中。
routine: 指向清理函数的函数指针,清理函数没有返回值,并接受一个 void * 类型的参数。
arg: 传递给清理函数的参数,当清理函数执行时,该参数作为 routine() 的输入。
pthread_cleanup_pop():用于从清理函数栈中弹出最近添加的清理函数。
execute: 指定是否执行清理函数。如果为 0,则只移除清理函数而不执行它;如果为非 0,则不仅移除还会执行清理函数。
线程清理函数执行的场景:
当线程调用 pthread_exit()退出时,清理函数会自动执行。
当线程响应取消请求时(如通过 pthread_cancel()取消线程),清理函数会被执行。
当通过非 0 参数调用 pthread_cleanup_pop() 时,栈顶的清理函数会被执行。
以下代码展示了如何使用 pthread_cleanup_push() 和 pthread_cleanup_pop() 注册和移除清理函数:
void cleanup(void *arg) {
printf("Cleaning up: %s\n", (char *)arg);
}
void *thread_function(void *arg) {
pthread_cleanup_push(cleanup, "Resource 1");
pthread_cleanup_push(cleanup, "Resource 2");
// 模拟线程工作
printf("Thread is running...\n");
// 调用pthread_exit()会触发清理函数的执行
pthread_exit(NULL);
// 清理函数必须成对使用,因此即使退出后也要调用pthread_cleanup_pop
pthread_cleanup_pop(1);
pthread_cleanup_pop(1);
}
int main() {
pthread_t thread;
// 创建一个线程
if (pthread_create(&thread, NULL, thread_function, NULL) != 0) {
perror("Failed to create thread");
return 1;
}
// 等待线程结束
pthread_join(thread, NULL);
return 0;
}解释说明:
线程中注册了两个清理函数,分别为 "Resource 1" 和 "Resource 2"。
当线程调用 pthread_exit() 时,栈中的清理函数按后进先出的顺序执行,因此会先打印 "Cleaning up: Resource 2",再打印 "Cleaning up: Resource 1"。
注意事项:
pthread_cleanup_push() 和 pthread_cleanup_pop() 并不是普通函数,而是宏实现的,必须在相同的作用域内成对出现,不能在代码中分开使用。
清理函数只会在线程通过 pthread_exit() 或响应取消请求时执行。
如果线程通过 return 语句退出,清理函数不会被执行。
通过使用 pthread_cleanup_push() 和 pthread_cleanup_pop(),可以确保在线程终止时执行所需的清理操作,这在资源管理和异常处理中非常有用。
清理函数的自动执行使得多线程编程中的资源释放更加简洁、安全。
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。
相关推荐
华清远见嵌入式在线视频教程——4、基于ARM的嵌入式开发
华清远见嵌入式在线视频教程——3、嵌入式Linux开发应用介绍
linux入门精华
研华模块化电脑SOM-7583:通过模块化架构应对人形机器人应用挑战
LCD驱动器SD0432与嵌入式系统的接口设计
Linux系统下USB摄像头驱动开发
米尔亮相德国嵌入式展2026 Embedded World
大家在互相借鉴吧!--嵌入式系统词汇表
汽车存储器新突破:8nm128Mb嵌入式MRAM的研发
嵌入式操作系统大比拼
从COM到SMARC再到OSM:嵌入式计算模块的发展
未来倾向于UFS用于高性能嵌入式闪存
LAN91C111型控制器在嵌入式以太网接口中的应用
FFT公司9200的板子的资料
TI将边缘AI微控制器更深入地融入嵌入式设计
一款用于远程嵌入式设计的机器人
华清远见嵌入式在线视频教程——1、走近嵌入式系统
大家在互相借鉴吧!--嵌入式系统词汇表
RK3576 + ROS2 SLAM建图与导航实战
[链接]Firefox_ 重新发现网络
华清远见嵌入式在线视频教程——2、嵌入式系统的选择与开发
大家在互相借鉴吧!--嵌入式系统词汇表
嵌入式U盘读写器接口技术和系统设计
IAR 扩展了嵌入式开发平台,提供 LTS 服务
ARM 开发板使用手册 在三星 S3C2410开发板上烧写linux
U-BOOT 与 MontaVista Linux 的移植
嵌入式系统的实时数据接口扩展
华清远见嵌入式在线视频教程——5、嵌入式Linux移植和u-boot
展会预告!米尔邀您相约德国嵌入式展 2026Embedded World
大家在互相借鉴吧!--嵌入式系统词汇表