pthread 线程退出时自动释放资源

线程退出时自动释放资源
今天碰到一个问题:主线程pthread_create一个子线程A,子线程pthread_mutex_lock,然后调用其他的函数fun,最后从fun返回后再pthread_mutex_unlock.
但是如果在fun中调用了pthread_exit异常退出,那么岂不是没释放锁就退出了,这肯定会引起死锁.

解决办法一:
在fun中调用pthread_exit之前都先调用pthread_mutex_lock释放锁,
但是这就需要吧mutex作为参数传给fun,如果fun再调用了其他函数,就得一层一层的把mutex传下去,
而且要找到fun及其调用的函数中的pthread_exit然后再修改是很麻烦的,如果fun是一个第三方程序,而且退出是调用了exit而不是pthread_exit,那就更麻烦了.

解决办法二:
POSIX线程API中提供了一个pthread_cleanup_push()/pthread_cleanup_pop()函数对用于自动释放资源.
从pthread_cleanup_push()的调用点到pthread_cleanup_pop()之间的程序段中的终止动作(包括调用 pthread_exit()和取消点终止)都将执行pthread_cleanup_push()所指定的清理函数
API定义如下:
void pthread_cleanup_push(void (*routine) (void *), void *arg)
void pthread_cleanup_pop(int execute)

代码示例如下:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>#define THREAD_NUMBER 2
pthread_mutex_t mutex;void aa()
{pthread_exit(NULL);
}void* hello1(void *arg)
{ char *hello_str = (char *)arg;int oldtype;pthread_detach (pthread_self ()); pthread_cleanup_push(pthread_mutex_unlock, (void *) &mutex);pthread_mutex_lock(&mutex);sleep(2);printf("%s\n", hello_str);aa();pthread_mutex_unlock(&mutex);pthread_cleanup_pop(0);
}void* hello2(void *arg)
{char *hello_str = (char *)arg;pthread_detach (pthread_self ()); pthread_mutex_lock(&mutex);sleep(1);printf("%s\n", hello_str);pthread_mutex_unlock(&mutex);
}int main(int argc, char *argv[])
{int i;int ret_val;pthread_t pt[THREAD_NUMBER];const char *arg[THREAD_NUMBER];arg[0] = "hello world from thread1";arg[1] = "hello world from thread2";pthread_mutex_init(&mutex,NULL);printf("Begin to create threads...\n");ret_val = pthread_create(&pt[0], NULL, hello1, (void *)arg[0]);if (ret_val != 0 ) {printf("pthread_create error!\n");exit(1);}ret_val = pthread_create(&pt[1], NULL, hello2, (void *)arg[1]);if (ret_val != 0 ) {printf("pthread_create error!\n");exit(1);}sleep(5);printf("Now, the main thread returns.\n");return 0;
}

$ gcc -o a.out test.c -lpthread
$ ./a.out
Begin to create threads…
hello world from thread1
hello world from thread2
Now, the main thread returns.

可以看出hello1()->aa()->pthread_exit(),当线程hello1退出后锁已经释放了
其实不光是释放锁,还可以释放其他资源.

当然上述pthread_cleanup_push()/pthread_cleanup_pop()是有缺陷的,
比如线程处于PTHREAD_CANCEL_ASYNCHRONOUS状态,上述代码段就有可能出错,
因为CANCEL事件有可能在 pthread_cleanup_push()和pthread_mutex_lock()之间发生,或者在 pthread_mutex_unlock()和pthread_cleanup_pop()之间发生,从而导致清理函数unlock一个并没有加锁的 mutex变量,造成错误。
因此,在使用清理函数的时候,都应该暂时设置成PTHREAD_CANCEL_DEFERRED模式。为此,POSIX的 Linux实现中还提供了一对不保证可移植的 pthread_cleanup_push_defer_np()/pthread_cleanup_pop_defer_np()扩展函数

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

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

相关文章

逃离迷茫和枯燥,让自己快乐起来

-1-2017年末&#xff0c;佛系青年一词刷爆朋友圈&#xff0c;它跟宗教没有任何关系&#xff0c;代表一种怎么都行、不大走心、看淡一切的活法。佛系青年最喜欢的三个词就是就是&#xff1a;可以&#xff0c;都行&#xff0c;没关系。佛系青年口头禅快节奏的社会&#xff0c;压力…

电脑小技巧

电脑小技巧 第一个&#xff1a;修复旧电脑 winR&#xff08;注意勾选管理权限创建此任务&#xff09;然后输入cmd 输入chkdsk&#xff0c;然后回车 然后输入sfc/scannow&#xff0c;回车 在winr&#xff0c;然后输入%temp%,全选删除。 截图 windowshifts:任意截图。…

工程应用中的自相关操作

作者&#xff1a;桂。 时间&#xff1a;2018-01-10 18:41:05 链接&#xff1a;http://www.cnblogs.com/xingshansi/p/8260315.html 前言 主要记录工程应用中的自相关操作&#xff0c;以及自相关的一些理论性质。 代码实现可参考&#xff1a;Xilinx 常用模块汇总(verilog)【03…

Ubuntu 18.04 LTS环境下 MNN 的编译与使用

环境 Ubuntu 18.04 LTS 本文主要介绍从github上下载 MNN 后,如何快速的进行编译 1.安装C/C编译器 gcc 与 NDK #首先安装好gcc, 用来编译 MNN 中的工具等内容 sudo apt install build-essential gcc --version #其次, 安装NDK或者安装Android Studio, 然后安装NDK插件, #在h…

深圳多管齐下破解“融资难”

来源&#xff1a;深圳特区报 2018年01月09日 版次&#xff1a;A13■ 深圳特区报记者 沈勇 文/图“原来只能贷款850万元&#xff0c;后来却顺利地贷到1100万&#xff0c;而且利息并不高。”深圳一家高新技术企业的丁先生对自己在深圳某贷款服务公司的融资体验赞不绝口&#xff0…

建立时间和保持时间的模型分析

建立时间和保持时间的模型分析 起点是源触发器D1的采样时刻,终点是目的触发器D2的采样时刻,假设起点已经满足了建立时间和保持时间要求,现在分析终点采样时刻是否同样满足要求。 其中 Tco:数据正确采样后从D端到达Q端的延时,触发器固有属性,不可改变。TDelay:D1输出端…

虚拟机Ubuntu18.04 root下 连接 windows 中 winScp

Windows 下通过 WinSCP 和 Ubuntu 18.04 连接传输文件 基本原理是Windows下使用 ssh/scp 协议客户端软件WinSCP, Linux/Ubuntu 系统开启ssh/scp协议server服务. 先查看自己Linux/Ubuntu中是否有 ssh服务 如果没有的话先安装 apt-get install openssh-server安装完之后 先手…

年关节点,小心这9大贷款骗局

准备过年了&#xff0c;骗子也出来活动了&#xff0c;作为骗钱的高发区&#xff0c;贷款诈骗就是诈骗团伙重点盯住的肥肉。大家近段是否会经常接收到这样的短信&#xff1a;“银行贷款快速办理”、“无需抵押”、“当天放款”……岁末年初&#xff0c;此类推荐贷款的骚扰电话与…

全民熬夜的时代,如何做到早睡?

-1-2018&#xff0c;给自己定了一个小目标&#xff1a;坚持早睡。翻看2017年早睡的打卡记录&#xff0c;坏消息是有近一半的时间都超过11点入睡&#xff0c;而好消息就是&#xff0c;我每月早睡的完成率在稳步提升。改变要从暑假说起&#xff0c;那段时间自己状态很差&#xff…

电机的简介

电机的简介 通电导体在磁场中受到力的作用–安培力 洛仑磁力的合力。

编译Android版本TensorFlow

在Ubuntu 18.04 LTS 下编译Tensorflow的Android库的步骤&#xff1a; 安装Android Studio/Android sdk安装Android NDK(Android NDK可以单独安装也可以通过Android Studio的SDK插件安装, 怎么安装略)安装 能够编译Tensorflow的对应版本的Bazel, TensorFlow和 Bazel 有对应关系…

银监会周末突发4号文件,18年贷款比想象的要难

2018年1月13日&#xff0c;星期六&#xff0c;当大家都还在过周末的时候&#xff0c;银监会突然印发了《关于进一步深化整治银行业市场乱象的通知》&#xff08;以下简称《通知》&#xff09;&#xff0c;通知要求在全国范围内进一步深化整治银行业市场乱象&#xff0c;切实巩固…

FPGA内部硬件结构与代码的关系

FPGA内部硬件结构与代码的关系 I/O的映射 给一个输入信号,然后不进行任何逻辑运算直接输出。 module line(input wire in,output wire out);assign out = in; endmodule组合逻辑的映射 module line(input wire in1,input wire in2,output wire out);assign out = in1 &a…

消费金融资金断流,银行抽贷、通道暂停,P2P离场

最近消费金融发展可谓焦躁不安&#xff0c;监管加压&#xff0c;资金断流&#xff0c;客户流失、逾期飙升&#xff0c;来自各方面的压力&#xff0c;让消费金融&#xff0c;特别是现金贷的出路前途未卜。01消费金融在中国有点水土不服消费金融在我国的发展是最近几年才兴起的&a…

SKF密码设备研究

密码设备 mToken GM3000 国密身份认证锁是龙脉科技自主研发设计支持国密算法、完全遵照国家密码管理局颁布的《智能IC卡及智能密码钥匙密码应用接口规范》要求设计的USB Key&#xff0c;采用国产高性能智能卡芯片&#xff0c;内置SSF33、SM1、SM2、SM3、SM4等国产算法&#xf…

微信礼仪测试,你能及格吗?

插图&#xff1a;annie.Z“群主&#xff0c;我可以打个广告吗&#xff1f;”还没等我回复&#xff0c;对方已经把自己产品的介绍丢在了微信群。提醒他撤回&#xff0c;刚刚还在发信息的他突然不见了。2分钟后又出现&#xff0c;“不好意思啊群主&#xff0c;超过2分钟不能撤回了…

AMBA总线介绍

AMBA总线介绍 系统总线简介 系统芯片中各个模块之间需要要有接口来连接 总线作为子系统之间共享的通信链路 优点&#xff1a;低成本&#xff0c;方便易用 缺点&#xff1a;会造成性能颈瓶 AMBA&#xff1a;Advanced Microcontroller Bus Architecture。片总线的标准 定义了三…

gradle之gradlew最全指令攻略

Gradle是一个构建工具&#xff0c;它是用来帮助我们构建app的&#xff0c;构建包括编译、打包等过程。我们可以为Gradle指定构建规则&#xff0c;然后它就会根据我们的“命令”自动为我们构建app。Android Studio中默认就使用Gradle来完成应用的构建&#xff0c;除此之外我们可…

去杠杆高歌猛进,借呗会倒闭吗?

最近马云烦心事貌似挺多的&#xff0c;从收购美国大型汇款公司MoneyGram&#xff08;速汇金&#xff09;被否&#xff0c;到支付宝年度账单默认勾选协议“惹祸”被监管约谈&#xff0c;再到消费金融业务因高杠杆或触及监管红线引发关注&#xff0c;蚂蚁金服的2018年开年看起来不…

能过好每一天的人,都不会混得太差

-1-朋友发来一张很有意思的图片。计划2018年坚持写日记&#xff0c;算了&#xff0c;还是坚持发朋友圈吧。计划读10本书&#xff0c;算了&#xff0c;9本吧&#xff0c;要不干脆8本&#xff1f;不行就7本&#xff1f;好了好了&#xff0c;只读1本。……如果没有猜错的话&#x…