POSIX 线程取消与资源清理完全指南

POSIX 线程取消与资源清理完全指南

引言:为什么需要线程取消机制?

在多线程编程中,优雅地终止线程并确保资源释放是开发者面临的重要挑战。直接终止线程可能导致内存泄漏、文件未关闭等问题。POSIX 线程库提供了一套完整的线程取消和清理机制,本文将深入解析这些关键API的使用方法。


一、线程终止的三种方式

  1. 隐式终止:线程函数执行return
  2. 显式终止:调用pthread_exit()
  3. 强制终止:通过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;
}

六、最佳实践与注意事项

  1. 资源管理三原则

    • 每个资源申请操作后立即注册清理函数
    • 使用结构体组织相关资源
    • 清理函数中实现幂等操作
  2. 取消点设计

    • 在循环体内定期调用pthread_testcancel()
    • 避免在临界区设置取消点
    • 对关键操作临时禁用取消
  3. 错误处理

    if(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL) != 0) {// 错误处理...
    }
    
  4. 调试技巧

    • 使用GDB观察清理栈:info threads + thread apply all bt
    • 记录清理函数执行日志
    • 使用Valgrind检测资源泄漏

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/41775.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【区块链安全 | 第七篇】EVM概念详解

文章目录 1. EVM 概述以太坊虚拟机&#xff08;Ethereum Virtual Machine&#xff0c;EVM&#xff09;的作用EVM 如何执行智能合约账户类型 2. EVM 体系结构栈&#xff08;Stack&#xff09;内存&#xff08;Memory&#xff09;存储&#xff08;Storage&#xff09;Gas 机制 3.…

【C++】AVL树

目录 前言平衡二叉树的定义AVL树的插入AVL树插入的大致过程更新平衡因子调整最小不平衡因子左单旋右单旋左右双旋右左双旋 AVL树的删除AVL树的查找 前言 前面我们在数据结构中学习了树&#xff0c;以及二叉树&#xff0c;还有二叉排序树&#xff0c;这节来学习平衡二叉树。 数…

【洛谷题单】暴力枚举(上)

【前情提要】 此文章包含洛谷题单的枚举题单&#xff0c;共14题&#xff0c;本篇7道题&#xff0c;主要分析思路&#xff0c;并通过这几道题目&#xff0c;进行总结有关枚举的内容。所以内容比较多&#xff0c;可以先收藏起来&#xff0c;慢慢看。 题单链接&#xff1a;暴力枚…

JVM类加载过程详解

文章目录 前言1.加载2.链接验证文件格式验证元数据验证字节码验证符号引用验证 准备解析 3.初始化4.类卸载 前言 类从被加载到虚拟机内存中开始到卸载出内存为止&#xff0c;它的整个生命周期可以简单概括为 7 个阶段&#xff1a;加载&#xff08;Loading&#xff09;、验证&a…

python之并发编程

并发编程介绍 串行、并行与并发的区别 进程、线程、协程的区别 1. 进程 (Process) 定义&#xff1a;进程是操作系统为运行中的程序分配的基本单位。每个进程都有独立的地址空间和资源&#xff08;如内存、文件句柄等&#xff09;。特点&#xff1a; 进程是资源分配的基本单位…

批量优化与压缩 PPT,减少 PPT 文件的大小

我们经常能够看到有些 PPT 文档明明没有多少内容&#xff0c;但是却占用了很大的空间&#xff0c;存储和传输非常的不方便&#xff0c;这时候通常是因为我们插入了一些图片/字体等资源文件&#xff0c;这些都可能会导致我们的 PPT 文档变得非常的庞大&#xff0c;今天就给大家介…

centos 7 LVM管理命令

物理卷&#xff08;PV&#xff09;管理命令 pvcreate&#xff1a;用于将物理磁盘分区或整个磁盘创建为物理卷。 示例&#xff1a;sudo pvcreate /dev/sdb1 解释&#xff1a;将 /dev/sdb1 分区创建为物理卷。 pvdisplay&#xff1a;显示物理卷的详细信息&#xff0c;如大小、所属…

b站视频提取mp4方案

引言 对于b站视频&#xff0c;有些视频是不能提取字幕的&#xff0c;所以我们想把对应的视频下载下来&#xff0c;然后进行对应的本地处理&#xff0c;获得所需的自由处理&#xff0c;吞食视频。 整体思路 下载b站客户端 ----> 把缓存路径修改------> 下载所需视频---…

springboot在feign和线程池中使用TraceId日志链路追踪(最终版)-2

文章目录 简述问题feign调用时给head加入traceIdFeignConfig配置FeignConfig 局部生效feign拦截器和配置合并为一个文件&#xff08;最终版&#xff09;feign异步调用拦截器配置[不常用] 使用TTL自定义线程池为什么需要TransmittableThreadLocal&#xff1f; 总结参考和拓展阅读…

MySQL数据库单表与多表查询

一.单表查询 1.创建用于数据查询的数据库表 CREATE TABLE worker (部门号 int(11) NOT NULL,职工号 int(11) NOT NULL,工作时间 date NOT NULL,工资 float(8,2) NOT NULL,政治面貌 varchar(10) NOT NULL DEFAULT 群众,姓名 varchar(20) NOT NULL,出生日期 date NOT NULL,PRIM…

海外紧固件市场格局与发展趋势研究报

一、引言 紧固件作为各类机械装备、建筑结构以及电子设备中不可或缺的基础性零部件&#xff0c;在国民经济的各个领域都有着广泛应用。其市场动态与全球经济发展态势以及各行业的兴衰紧密相连。在全球化进程不断加速、产业分工日益精细的大背景下&#xff0c;深入研究海外紧固…

【多学科稳定EI会议大合集】计算机应用、通信信号、电气能源工程、社科经管教育、光学光电、遥感测绘、生物医学等多学科征稿!

在当今科技高速发展的时代&#xff0c;多学科领域的学术交流与融合显得尤为重要。以下是稳定EI会议合集&#xff0c;涵盖计算机、信息通信、电气能源、社科经管教育、光学遥感、生物医学等多个学科领域。 会议皆已通过国际知名出版社出版审核&#xff0c;EI检索稳定&#xff0…

【深度学习新浪潮】展平RVQ技术详解

展平 RVQ(Flattened Residual Vector Quantization)是一种基于矢量量化(Vector Quantization, VQ)的技术,主要用于高效地表示和压缩数据(例如图像、音频或文本嵌入)。它结合了**残差矢量量化(Residual Vector Quantization, RVQ)**的思想与“展平”操作,从而进一步优…

【第23节】windows网络编程模型(WSAEventSelect模型)

目录 引言 一、WSAEventSelect模型概述 二、 WSAEventSelect模型的实现流程 2.1 创建一个事件对象&#xff0c;注册网络事件 2.2 等待网络事件发生 2.3 获取网络事件 2.4 手动设置信号量和释放资源 三、 WSAEventSelect模型伪代码示例 四、完整实践示例代码 引言 在网…

LlamaFactory部署及模型微调【win10环境】

1.Llama-Factory简介 LLaMA-Factory&#xff0c;全称 Large Language Model Factory&#xff0c;旨在简化大模型的微调过程&#xff0c;帮助开发者快速适应特定任务需求&#xff0c;提升模型表现。它支持多种预训练模型和微调算法&#xff0c;适用于智能客服、语音识别、机器翻…

Jmeter简介、学习目标及安装启动

1. 简介 JMeter 是 Apache 组织使用 Java 开发的一款测试工具&#xff1a;可以用于对服务器、网络或对象模拟巨大的负载&#xff1b;通过创建带有断言的脚本来验证程序是否能返回期望的结果。 1&#xff09;优点&#xff1a;开源、免费&#xff1b;跨平台&#xff1b;支持多协…

无参数读文件和RCE

什么是无参数&#xff1f; 无参数&#xff08;No-Argument&#xff09;的概念&#xff0c;顾名思义&#xff0c;就是在PHP中调用函数时&#xff0c;不传递任何参数。我们需要利用仅靠函数本身的返回值或嵌套无参数函数的方式&#xff0c;达到读取文件或远程命令执行&#xff0…

细胞内与细胞间网络整合分析!神经网络+细胞通讯,这个单细胞分析工具一箭双雕了(scTenifoldXct)

生信碱移 细胞间-细胞内通讯网络分析 scTenifoldXct&#xff0c;一种结合了细胞内和细胞间基因网络的计算工具&#xff0c;利用 scRNA-seq 数据检测细胞间相互作用。 单细胞 RNA 测序&#xff08;scRNA-seq&#xff09;能够以稳健且可重复的方式同时收集数万个细胞的转录组信息…

怎么处理 Vue 项目中的错误的?

一、错误类型 任何一个框架,对于错误的处理都是一种必备的能力 在Vue 中,则是定义了一套对应的错误处理规则给到使用者,且在源代码级别,对部分必要的过程做了一定的错误处理。 主要的错误来源包括: 后端接口错误代码中本身逻辑错误二、如何处理 后端接口错误 通过axi…

05.AI搭建preparationの(transformers01)BertTokenizer实现分词编码

一、下载 bert-base-chinese镜像下载 二、简介作用&#xff1a; 模型每个参数占用的字节大小模型大小模型大小层数头数GPT-14 个字节的 FP32 精度浮点数117M446MB1212GPT-22 个字节的 FP161.5亿到1.75亿0.5GB到1.5GB4816GPT-32 个字节的 FP161.75万亿&#xff08;17500亿&a…