当前位置: 首页 > news >正文

线程清理机制(pthread_cleanup函数族实践)

#include <unistd.h>      // 提供 sleep() 函数
#include <pthread.h>     // 多线程编程
#include <stdio.h>       // 标准输入输出
#include <string.h>      // 字符串处理
#include <stdlib.h>      // 内存分配#define  PI  3.1415      // 圆周率常量// 第一个清理处理函数
void clean(void* argp)
{puts("异常终止,清理函数被执行!");if(argp)free(argp);  // 释放动态分配的内存
}// 第二个清理处理函数(被注释掉了)
void clear(void* argp)
{puts("异常终止,清理函数2被执行!");
}// 线程1的执行函数:计算圆的面积
void* routine(void* argp)
{int* p = (int*)malloc(sizeof(int));  // 分配内存存储结果// 注册清理处理函数(压入清理栈)// 参数:清理函数指针,传递给清理函数的参数pthread_cleanup_push(clean, p);// pthread_cleanup_push(clear,p);  // 第二个清理函数被注释for(int i = 1; ; i++){printf("开始圆的面积计算(%d)\n",i);if(PI*i*i > 150.0)  // 当面积超过150时退出循环{*p = i;         // 存储结果break;          // 正常退出循环} sleep(1);           // 休眠1秒(取消点)}// 弹出清理处理函数,参数0表示不执行清理函数pthread_cleanup_pop(0);// pthread_cleanup_pop(0);  // 第二个弹出被注释pthread_exit(p);        // 正常退出线程,返回结果return NULL;            // 这行不会执行到
}// 线程2的执行函数:负责取消线程1
void* routine2(void* argp)
{pthread_t id = *((pthread_t*)argp);  // 获取线程1的IDprintf("1秒后向线程(%lu)发送退出请求\n",id);sleep(10);              // 等待10秒(注意:这里改成了10秒!)pthread_cancel(id);     // 发送取消请求return NULL;
}int main(int argc,char** argv)
{pthread_t id, id2;      // 线程ID// 创建线程1(计算线程)int error = pthread_create(&id, NULL, routine, NULL);if(error){puts(strerror(error));return -1;}// 创建线程2(取消线程)error = pthread_create(&id2, NULL, routine2, &id);if(error){puts(strerror(error));return -1;}int *pret = NULL;       // 用于接收线程1的返回值// 等待线程1结束if(error = pthread_join(id, (void**)&pret)){printf("Join:%s\n",strerror(error));return -1;}puts("线程1已经结束");// 检查线程1的退出状态if(pret && pret != PTHREAD_CANCELED){printf("子线程1退出值:%d\n",*pret);           // 输出半径值printf("子线程正常退出,主线程回收资源\n");     // 提示信息free(pret);         // 释放内存}// 等待线程2结束pthread_join(id2, NULL);puts("线程2已经结束");return 0; 
}

关键机制详解

1. pthread_cleanup_push 和 pthread_cleanup_pop

pthread_cleanup_push(clean, p);  // 注册清理函数
// ... 线程代码 ...
pthread_cleanup_pop(0);          // 移除清理函数,不执行

清理函数执行时机:

  • 线程被 pthread_cancel() 取消时

  • 线程调用 pthread_exit() 退出时

  • 线程调用 pthread_cleanup_pop(1) 时

2. pthread_cleanup_pop 参数含义

pthread_cleanup_pop(0);  // 移除清理函数但不执行
pthread_cleanup_pop(1);  // 移除清理函数并执行

3. 程序执行逻辑分析

情况1:计算先完成(大概率)

  • 线程1在约7秒内完成计算(i=7时面积153.94>150)

  • 线程2等待10秒后才发送取消请求

  • 线程1正常退出,清理函数不会执行

  • 主线程正常回收资源

执行流程:

开始圆的面积计算(1)
1秒后向线程(12345678)发送退出请求
开始圆的面积计算(2)
...
开始圆的面积计算(7)        ← 正常完成计算
线程1已经结束
子线程1退出值:7
子线程正常退出,主线程回收资源
线程2已经结束

情况2:被取消(小概率,如果计算很慢)

  • 线程1计算超过10秒

  • 线程2发送取消请求

  • 线程1在sleep(1)取消点响应

  • 清理函数执行

内存管理分析

正常退出路径:

break;                          // 退出循环
pthread_cleanup_pop(0);         // 不执行清理函数
pthread_exit(p);                // 返回指针p
// 主线程中:
free(pret);                     // 主线程释放内存

被取消路径:

// 在sleep(1)时被取消
clean(p);                       // 清理函数执行,free(p)
// 主线程中:
pret == PTHREAD_CANCELED        // 不会进入free(pret)分支

潜在问题

  1. 竞争条件:线程2等待10秒,线程1约7秒完成,所以线程1几乎总是正常完成

  2. 内存双重释放:如果清理函数执行了free(p),而主线程又执行free(pret),会导致崩溃

  3. sleep(10)过长:线程2等待10秒,而线程1只需要约7秒,取消很少发生

改进建议

// 修改线程2的等待时间
sleep(3);  // 改为3秒,增加取消的概率// 或者在主线程中完善取消情况的处理
if(pret == PTHREAD_CANCELED) {printf("线程1被取消\n");
} else if(pret != NULL) {printf("子线程1正常退出,返回值:%d\n",*pret);free(pret);
}
http://www.dtcms.com/a/432330.html

相关文章:

  • 轻淘客的轻网站怎么做wordpress js cdn
  • 网站注册商是什么个人作品集模板免费
  • 网站退出率用php做京东网站页面
  • 电子商务网站后台功能wordpress首页文章带图
  • php网站开发软件语言c php做网站对比
  • 江门网站seo推广建设银行河北省分行网站
  • 器件选型时,几个重要通识与应用案例分享
  • 时间复杂度与空间复杂度知识框架
  • 关于建设网站群的报告wordpress 记录密码
  • Python基础编程中的变量操作和字符串处理
  • 异步事件处理(注册与回调)——C函数指针总结分享一般用途篇
  • 科技部网站建设合同范本网络营销的特点有哪些
  • asp.net网站开发 vs2017静态网站开发篇
  • Integrated Sensing and Communications in Clutter Environment
  • 在百度建免费网站吗牡丹江百姓信息网
  • 平台网站如何优化asp.net网站开发第一步
  • 服装公司 网站怎么做网页界面设计中表单的组成部分有
  • 网站作品集wordpress系统要求
  • 教育培训网站案例网站建设计无形资产
  • 爬虫的“Cookie”管理艺术:维持登录状态与会话
  • 网站设计专题页大理市建设局网站
  • 【代码随想录day 30】 力扣 763. 划分字母区间
  • 网站百度忽然搜索不到模板制作方法
  • 上海电子通科技网站建设网页设计制作是干什么的
  • 科普:Python 中`str.join(iterable)` 方法用于逻辑连接
  • php网站模板外贸怎样做网站
  • 网站效果图设计思路网页设计尺寸的分辨率
  • 南京汽车 企业 网站建设网站建设做网站怎么做
  • 如何把网站和域名绑定网站备案号 脱离服务商
  • 陕西煤化建设集团铜川分公司网站判断网站开发语言