POSIX 线程取消与资源清理完全指南
POSIX 线程取消与资源清理完全指南
引言:为什么需要线程取消机制?
在多线程编程中,优雅地终止线程并确保资源释放是开发者面临的重要挑战。直接终止线程可能导致内存泄漏、文件未关闭等问题。POSIX 线程库提供了一套完整的线程取消和清理机制,本文将深入解析这些关键API的使用方法。
一、线程终止的三种方式
- 隐式终止:线程函数执行
return - 显式终止:调用
pthread_exit() - 强制终止:通过
pthread_cancel()请求取消
⚠️ 注意:直接使用
return退出线程不会触发清理函数!
二、线程取消请求机制
1. pthread_cancel()
int pthread_cancel(pthread_t thread);
- 功能:向目标线程发送取消请求
- 特性:
- 非阻塞操作
- 实际终止时机取决于线程的取消状态和类型
- 常见取消点:sleep(), read(), pthread_join()等阻塞调用
2. pthread_testcancel()
void pthread_testcancel(void);
- 作用:显式创建取消点
- 应用场景:
- 长时间运行的循环中插入检查点
- 非阻塞代码路径中主动响应取消请求
// 示例:在计算密集型循环中添加取消检查
while(1) {pthread_testcancel();// 复杂计算...
}
三、取消状态与类型控制
1. 状态控制 pthread_setcancelstate()
int pthread_setcancelstate(int state, int *oldstate);
| 状态值 | 说明 |
|---|---|
| PTHREAD_CANCEL_ENABLE | 允许取消(默认) |
| PTHREAD_CANCEL_DISABLE | 禁止取消请求 |
2. 类型控制 pthread_setcanceltype()
int pthread_setcanceltype(int type, int *oldtype);
| 类型值 | 说明 |
|---|---|
| PTHREAD_CANCEL_DEFERRED | 延迟取消(默认) |
| PTHREAD_CANCEL_ASYNCHRONOUS | 异步取消(立即终止) |
🔑 最佳实践:异步取消应谨慎使用,可能导致资源未释放!
四、线程清理函数
1. 注册清理函数
void pthread_cleanup_push(void (*routine)(void*), void* arg);
2. 注销清理函数
void pthread_cleanup_pop(int execute);
3. 关键特性
- 后进先出(LIFO)执行顺序
- 触发条件:
- 调用
pthread_exit() - 线程被取消
- 执行
pthread_cleanup_pop(1)
- 调用
4. 典型应用模式
void* thread_func(void* arg) {FILE *fp = fopen("data.txt", "r");pthread_cleanup_push(cleanup_file, fp);while(1) {// 文件操作...pthread_testcancel();}pthread_cleanup_pop(1); // 正常退出时主动清理return NULL;
}void cleanup_file(void* arg) {FILE *fp = (FILE*)arg;if(fp) {fclose(fp);printf("File closed\n");}
}
五、完整示例:安全的线程取消
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>typedef struct {int *buffer;FILE *logfile;
} ThreadResource;void cleanup_handler(void *arg) {ThreadResource *res = (ThreadResource *)arg;printf("Cleaning up resources...\n");if (res->buffer) {free(res->buffer);res->buffer = NULL;}if (res->logfile) {fclose(res->logfile);res->logfile = NULL;}
}void* worker_thread(void *arg) {ThreadResource resources = {0};// 申请资源resources.buffer = malloc(1024);resources.logfile = fopen("thread.log", "w");// 注册清理函数pthread_cleanup_push(cleanup_handler, &resources);// 设置取消类型为延迟取消pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);while(1) {// 模拟工作fprintf(resources.logfile, "Working...\n");sleep(1);// 显式取消点pthread_testcancel();}// 正常退出时执行清理pthread_cleanup_pop(1);return NULL;
}int main() {pthread_t tid;pthread_create(&tid, NULL, worker_thread, NULL);sleep(3);printf("Requesting thread cancellation...\n");pthread_cancel(tid);pthread_join(tid, NULL);printf("Thread terminated safely\n");return 0;
}
六、最佳实践与注意事项
-
资源管理三原则:
- 每个资源申请操作后立即注册清理函数
- 使用结构体组织相关资源
- 清理函数中实现幂等操作
-
取消点设计:
- 在循环体内定期调用pthread_testcancel()
- 避免在临界区设置取消点
- 对关键操作临时禁用取消
-
错误处理:
if(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL) != 0) {// 错误处理... } -
调试技巧:
- 使用GDB观察清理栈:
info threads+thread apply all bt - 记录清理函数执行日志
- 使用Valgrind检测资源泄漏
- 使用GDB观察清理栈:
相关文章:
POSIX 线程取消与资源清理完全指南
POSIX 线程取消与资源清理完全指南 引言:为什么需要线程取消机制? 在多线程编程中,优雅地终止线程并确保资源释放是开发者面临的重要挑战。直接终止线程可能导致内存泄漏、文件未关闭等问题。POSIX 线程库提供了一套完整的线程取消和清理机…...
FPGA学习篇——Verilog学习之寄存器的实现
1 寄存器理论 这里在常见的寄存器种加了一个复位信号sys_rst_n。(_n后缀表示复位信号低电平有效,无这个后缀的则表示高电平有效) 这里规定在时钟的上升沿有效,只有当时钟的上升沿来临时,输出out 才会改变,…...
Cursor异常问题全解析-无限使用
title: Cursor异常问题全解析无限使用 tags: cursor categories:aiai编程 mathjax: true description: Cursor异常问题全解析与解决方案大全 abbrlink: 64908bd0 date: 2025-03-19 14:48:32 🤖 Assistant 🚨 Cursor异常问题全解析与解决方案大全 &…...
【VUE】ant design vue实现表格table上下拖拽排序
适合版本:ant design vue 1.7.8 实现效果: 代码: <template><div class"table-container"><a-table:columns"columns":dataSource"tableData":rowKey"record > record.id":row…...
Vue实现动态数据透视表(交叉表)
需求:需要根据前端选择的横维度、竖维度、值去生成一个动态的表格,然后把交叉的值放入到对应的横维度和竖维度之下,其实就是excel里面的数据透视表功能,查询交叉语句为sql语句。 实现页面: 选择一下横维度、竖维度、值之后点击查…...
推荐《人工智能算法》卷1、卷2和卷3 合集3本书(附pdf电子书下载)
今天,咱们就一同深入探讨人工智能算法的卷1、卷2和卷3,看看它们各自蕴含着怎样的奥秘,并且附上各自的pdf电子版免费下载地址。 《人工智能算法(卷1):基础算法》 下载地址:https://www.panziye…...
元宇宙浪潮下,数字孪生如何“乘风破浪”?
在当今科技飞速发展的时代,元宇宙的概念如同一颗璀璨的新星,吸引了全球的目光。元宇宙被描绘为一个平行于现实世界、又与现实世界相互影响且始终在线的虚拟空间,它整合了多种前沿技术,为人们带来沉浸式的交互体验。而数字孪生&…...
WPF 附加属性
在WPF(Windows Presentation Foundation)中,附加属性(Attached Properties)是一种特殊的依赖属性机制,它允许父元素为子元素提供额外的属性支持。这种特性特别适用于布局系统、输入处理和其他需要跨多个控件…...
数据分析 之 怎么看懂图 一
韦恩图怎么看 ①颜色:不同颜色代表不同的集合 ②)颜色重叠部分:表示相交集合共有的元素 ③颜色不重叠的部分:表示改集合独有的元素 ④数字:表示集合独有或共有的元素数量 ⑤百分比:表示该区域元素数占整体的比例 PCA图怎么看 ① 第一主成分坐标轴及主成分贡献率主成分贡献…...
手写数据库MYDB(一):项目启动效果展示和环境配置问题说明
1.项目概况 这个项目实际上就是一个轮子项目,现在我看到的这个市面上面比较火的就是这个首先RPC,好多的机构都在搞这个,还有这个消息队列之类的,但是这个是基于MYSQL的,我们知道这个MYSQL在八股盛宴里面是重点考察对象…...
深入理解椭圆曲线密码学(ECC)与区块链加密
椭圆曲线密码学(ECC)在现代加密技术中扮演着至关重要的角色,广泛应用于区块链、数字货币、数字签名等领域。由于其在提供高安全性和高效率上的优势,椭圆曲线密码学成为了数字加密的核心技术之一。本文将详细介绍椭圆曲线的基本原理…...
使用 PowerShell 脚本 + FFmpeg 在 Windows 系统中批量计算 MP4视频 文件的总时长
步骤 1:安装 FFmpeg 访问 FFmpeg 官网(Download FFmpeg),下载 Windows 版编译包(如 ffmpeg-release-full.7z)。或者到(https://download.csdn.net/download/zjx2388/90539014)下载完整资料 解压文件&#…...
中医气血精津辨证
中医气血精津辨证 一、气血精津辨证概述 基本概念: 气血精津是构成人体和维持生命活动的基本物质,其生成、运行、输布与脏腑功能密切相关。辨证核心:通过分析气血精津的盛衰、运行障碍及其相互关系,判断疾病本质。 生理关系&…...
Intellij IDEA2023 创建java web项目
Intellij IDEA2023 创建java web项目 零基础搭建web项目1、创建java项目2、创建web项目3、创建测试页面4、配置tomcat5、遇到的问题 零基础搭建web项目 小白一枚,零基础学习基于springMVC的web项目开发,记录开发过程以及中间遇到的问题。已经安装了Inte…...
Scrapy结合Selenium实现滚动翻页数据采集
引言 在当今的互联网数据采集领域,许多网站采用动态加载技术(如AJAX、无限滚动)来优化用户体验。传统的基于Requests或Scrapy的爬虫难以直接获取动态渲染的数据,而Selenium可以模拟浏览器行为,实现滚动翻页和动态内容…...
Node.js从0.5到1学习计划
以下是针对零基础学习者的10天Node.js高效学习计划,每天聚焦核心知识点并配合实战练习: 📆 10天Node.js速成计划(每日4-6小时) 核心目标:掌握Node.js核心机制 完成3个实战项目 📍 Day 1-2&…...
python 的 obj的key 变成双引号
在Python中,当你序列化一个对象(例如使用json.dumps()方法将对象转换为JSON字符串)时,默认情况下,字典的键(keys)会被转换为字符串。如果你的字典中的键本身就是字符串,并且你想要在…...
sqlmap 源码阅读与流程分析
0x01 前言 还是代码功底太差,所以想尝试阅读 sqlmap 源码一下,并且自己用 golang 重构,到后面会进行 ysoserial 的改写;以及 xray 的重构,当然那个应该会很多参考 cel-go 项目 0x02 环境准备 sqlmap 的项目地址&…...
DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之添加行拖拽排序功能示例6,TableView16_06 分页表格拖拽排序
前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 目录 Deep…...
asp.net mvc 向前端响应json数据。用到jquery
最近在给客户开发提醒软件时,用asp.net mvc 开发。该框架已经集成了bootstrap,直接贴asp.net mvc 端代码: {Layout null; }<!DOCTYPE html><html> <head><meta name"viewport" content"widthdevice-width" /…...
基于物联网的新房甲醛浓度监测系统的设计(论文+源码)
2.1总体方案设计 本次基于物联网的新房甲醛浓度监测系统的设计其系统总体架构如图2.1所示,整个系统在硬件架构上采用了STM32f103作为主控制器,在传感器部分采用了MQ135实现甲醛浓度的检测,并且通过ESP8266 WiFi模块将当前检测的数据传输到手…...
deadsnakes
deadsnakes 是一个 第三方 PPA(Personal Package Archive),专门为 Ubuntu 系统提供较新版本的 Python,包括旧版本(如 Python 3.9)和开发中的测试版本。它的名称是一个幽默的双关,源自电影《Mont…...
Stable Diffusion 图标与像素风格LoRA训练的模型选择及参数设置
图标与像素风格LoRA训练的模型选择及参数设置指导意见 一、基础模型选型策略 图标生成推荐模型 Stable Diffusion 2.1-base 适用场景:通用UI图标、矢量风格设计核心优势:支持768x768分辨率,对几何形状捕捉精准需加载VAE模型:vae…...
【AI学习】人工神经网络
1,人工神经网络(Artificial Neural Networks,ANNs,连接模型,Connection Model) 模仿动物神经网络行为特征(突触联接的结构),进行分布式并行信息处理的算法数学模型。依靠系统的复杂程度,通过调整内部大量节点之间相互连接的关系,从而达到处理信息的目的。 2,前馈神…...
linux--网络协议初识
linux–网络协议初识 事实: 通信的主机之间距离变长了---->引发出新的通信问题? 如何使用数据问题(应用层)可靠性问题(传输层)主机定位问题(网络层)数据报局域网转发问题(数据链路层) 人提出网络协议解决方案—方案有好有坏–为了方便扩展,替换或维护–故将网络协议设置…...
Linux MariaDB部署
1:查看Linux系统版本 cat /etc/os-release#返回结果: NAME"CentOS Linux" VERSION"7 (Core)" ID"centos" ID_LIKE"rhel fedora" VERSION_ID"7" PRETTY_NAME"CentOS Linux 7 (Core)" ANSI…...
window系统下安装elk
Elasticsearch、logstash、kibana 都为8.17.3版本 Elasticsearch 安装流程 # 下载 https://www.elastic.co/cn/downloads/elasticsearch#ga-release elasticsearch-8.17.3-windows-x86_64 # 解压配置 elasticsearch.yml,下个代码块 # bin目录下双击下述文件&…...
uniapp用户登录及获取用户信息(头像昵称)
低版本情况 微信开发者工具的基础库版本要调到2.27版本以下,能够直接申请用户权限获取用户信息,但是会仅限于开发者调试,在真机测试或已上传的小程序在手机上就不能获取以上的原因是微信小程序wx.getUserProfile 和wx.getUserInfo 这两个获取…...
第五周日志-重新学汇编(2)
机器语言 汇编语言(直接在硬件上工作——硬件系统结构): 1.机器语言 每一种微处理器硬件设计和内部结构不同(决定了电信号不同,进而需要不同的机器指令) #早期通过纸带机/卡片机输入计算机,进行运算 2…...
Linux下EC11旋转编码器驱动调试
文章目录 1、前言2、使用gpio-keys驱动2.1、dts配置2.2、识别原理2.3、应用层驱动实现2.4、编译测试 3、使用rotary-encoder驱动3.1、dts配置3.2、app测试程序编写3.3、编译测试 4、总结 1、前言 本来是没有这篇文章的。最近在rk3576下调试ec11旋转编码器时,一直没…...
