浅谈可重入与线程安全
文章目录
- 可重入
- 与线程安全的关系
可重入
若一个程序或子程序可以“在任意时刻被中断然后操作系统调度执行另一段代码,这段代码又使用了该副程序不会出错”,则称其为可重入(reentrant 或 re-entrant)的。即当该副程序正在运作时,执行线程可以再次进入并执行它,仍然可得到符合设计时所预期的结果。与多线程并发执行的线程安全不同,可重入强调对单一线程执行时重新进入同一个子程序仍然是安全的。
若一个函数是可重入的,则该函数应当满足下述条件:
不能含有静态(全局)非常量数据。
不能返回静态(全局)非常量数据的地址。
只能处理由调用者提供的数据。
不能依赖于单例模式资源的锁。
调用(call)的函数也必需是可重入的。
上述条件就是要求可重入函数使用的所有变量都保存在调用堆栈的目前函数栈(frame)上,因此同一执行线程重入执行该函数时加载了新的函数帧,与前一次执行该函数时使用的函数帧不冲突、不互相覆盖,从而保证了可重入执行安全。
例子
在以下的C语言代码中,函数f和函数g都不是可重入的。
int g_var = 1;int f(){g_var = g_var + 2;return g_var;}int g(){return f() + 2;}
以上代码中,f使用了全局变量 g_var,所以,如果两个线程同时执行它并访问g_var,则返回的结果取决于执行的时间。因此,f不可重入。而g调用了f,所以它也不可重入。
稍作修改后,两个函数都是可重入的:
int f(int i){return i + 2;}int g(int i){return f(i) + 2;}
与线程安全的关系
游双,Linux书96,函数是不可重入,即非线程安全,应该表述有一些问题。
可重入与线程安全两个概念都关系到函数处理资源的方式。但是,他们有重大区别
可重入概念会影响函数的外部接口,而线程安全只关心函数的实现。
大多数情况下,要将不可重入函数改为可重入的,需要修改函数接口,使得所有的数据都通过函数的调用者提供。
要将非线程安全的函数改为线程安全的,则只需要修改函数的实现部分。一般通过加入同步机制以保护共享的资源,使之不会被几个线程同时访问。
操作系统背景与CPU调度策略:
可重入是在单线程操作系统背景下,重入的函数或者子程序,按照后进先出的线性序依次执行完毕。
多线程执行的函数或子程序,各个线程的执行时机是由操作系统调度,不可预期的,但是该函数的每个执行线程都会不时的获得CPU的时间片,不断向前推进执行进度。
可重入函数未必是线程安全的;线程安全函数未必是可重入的。
例如,一个函数打开某个文件并读入数据。这个函数是可重入的,因为它的多个实例同时执行不会造成冲突;但它不是线程安全的,因为在它读入文件时可能有别的线程正在修改该文件,为了线程安全必须对文件加“同步锁”。
另一个例子,函数在它的函数体内部访问共享资源使用了加锁、解锁操作,所以它是线程安全的,但是却不可重入。因为若该函数一个实例运行到已经执行加锁但未执行解锁时被停下来,系统又启动该函数的另外一个实例,则新的实例在加锁处将转入等待。如果该函数是一个中断处理服务,在中断处理时又发生新的中断将导致资源死锁。fprintf函数就是线程安全但不可重入。
下述例子,是线程安全的,但不是可重入的。
int function()
{mutex_lock();...function body...mutex_unlock();
}
多线程执行时,获得了互斥锁的线程总能获得CPU时间片,向前推进执行进度,最终解开互斥锁,使得别的线程也能获得互斥锁进入临界区。但是,如果在单线程背景下第一次执行该函数时已经获得互斥锁进入临界区,这时该函数被重入执行,这将在重新申请互斥锁时被饿死(starvation),因为获得了互斥锁的该函数的第一次执行将永远没有机会再获得CPU时间片。
相关文章:
浅谈可重入与线程安全
文章目录 可重入与线程安全的关系 可重入 若一个程序或子程序可以“在任意时刻被中断然后操作系统调度执行另一段代码,这段代码又使用了该副程序不会出错”,则称其为可重入(reentrant 或 re-entrant)的。即当该副程序正在运作时&…...

深入理解TDD(测试驱动开发):提升代码质量的利器
在日常的软件开发工作中,我们常常会遇到这样的问题:如何在繁忙的项目进度中,保证我们的代码质量?如何在不断的迭代更新中,避免引入新的错误?对此,有一种有效的开发方式能帮助我们解决这些问题&a…...

pyqt5使用pyqtgraph实现动态热力图
pyqt5使用pyqtgraph实现动态热力图 一、效果图 二、流程 1、打开Designer创建一个UI界面 2、把UI转成py 3、创建一个main.py文件 4、在main文件中渲染画布、创建初始数据、画热力图、创建更新数据线程、绑定按钮触发事件三、UI界面 其中h_map.py代码如下: # -*- coding: ut…...

【android开发-16】android中文件和sharedpreferences数据存储详解
1,文件读写方式的数据存储 下面是一个简单的示例,演示如何在Android中使用内部存储来保存和读取文件: 保存文件: try { String data "这是要保存的数据"; FileOutputStream fos openFileOutput("myFile"…...

《当代家庭教育》期刊论文投稿发表简介
《当代家庭教育》杂志是家庭的参谋和助手,社会的桥梁和纽带,人生的伴侣和知音,事业的良师益友。 国家新闻出版总署批准的正规省级教育类G4期刊,知网、维普期刊网收录。安排基础教育相关稿件,适用于评职称时的论文发表…...

【操作教程】如何将外省医保转入广州市区(医保转移接续手续办理)?
登录(可以用微信扫码采用粤省事账号登录,没有粤省事小程序账号的可以自主申请很方便)广东政务服务网https://www.gdzwfw.gov.cn/ 这里不得不吐槽官网开发者,太拉胯了,居然有undefined,多刷新几次就好了&…...

【分布式系统学习】CAP原理详解
CAP原理详解 前言CAP一张图 一、概念1.1 关键词解读1.2 关于CAP(拆分解读)1.3 CAP原理精髓 二、CAP模拟场景举例理解三、CAP原理证明为什么不能同时满足(下面举例说明)3.1 必须满足分区容错性P下的处理方式3.2 不是必须满足分区容…...
【聚类】K-modes和K-prototypes——适合离散数据的聚类方法
应用场景: 假设一批数据,每一个样本中,有唯一标识(id)、品类(cate_id)、受众(users, 小孩、老人、中年等)等属性,希望从其中找出一些样本,使得这…...

Python-炸弹人【附完整源码】
炸弹人 炸弹人是童年的一款经典电子游戏,玩家控制一个类似"炸弹人"的角色,这个角色可以放置炸弹,并在指定的时间内引爆它们消灭敌人以达到目标,此游戏共设有两节关卡,代码如下: 运行效果&#x…...

[英语学习][5][Word Power Made Easy]的精读与翻译优化
[序言] 今日完成第18页的阅读, 发现大量的翻译错误以及不准确. 需要分两篇文章进行讲解. [英文学习的目标] 提升自身的英语水平, 对日后编程技能的提升有很大帮助. 希望大家这次能学到东西, 同时加入我的社区讨论与交流英语相关的内容. [原著英文与翻译版对照][第18页] Wh…...

Apache Doris 详细教程(一)
1、Doris简介 1.1、doris概述 Apache Doris 由百度大数据部研发(之前叫百度 Palo,2018 年贡献到 Apache 社区后, 更名为 Doris ),在百度内部,有超过 200 个产品线在使用,部署机器超过 1000 台…...

【Vue3从入门到项目实现】RuoYi-Vue3若依框架前端学习——登录页面
若依官方的前后端分离版中,前端用的Vue2,这个有人改了Vue3的前端出来。刚好用来学习: https://gitee.com/weifengze/RuoYi-Vue3 运行前后端项目 首先运行项目 启动前端,npm install、npm run dev 启动后端,按教程配置…...

win11 关闭快速启动,解决重启后部分应用没有关闭的问题
鼠标右击win11开始菜单选择windows终端(管理员)打开输入:powercfg /h off按下回车即可...

python爬虫-某公开数据网站实例小记
注意!!!!某XX网站逆向实例仅作为学习案例,禁止其他个人以及团体做谋利用途!!! 第一步:分析页面和请求方式 此网站没有技巧的加密,仅是需要携带cookie和请求…...
还记得当初自己为什么选择计算机?
还记得当初自己为什么选择计算机? 当初你问我为什么选择计算机,我笑着回答:“因为我梦想成为神奇的码农!我想像编织魔法一样编写程序,创造出炫酷的虚拟世界!”谁知道,我刚入门的那天࿰…...

“数”说新语向未来 | GBASE南大通用2023媒体交流会成功举办
在当前国家信创战略加速实施,及国民经济数字化转型,叠加驱动信息化行业加速发展的大形势下,以“数说新语-GBASE南大通用开放创新再领航”为主题的2023 GBASE南大通用媒体交流日活动在GBASE天津总部举行。来自IT168、ITPUB、韩锋频道、自主可控…...

每天一点python——day88
#每天一点Python——88 #编程两大思想【面向过程与面向对象】 #如图: 面向过程的线性思维: 类似于做菜一步步的来,先怎么样怎么样,再怎么样 如果不一步步的来,例如先炒菜再点火,这样是做不好的 面向对象&a…...
xShell快捷键
Xshell 是一个强大的终端仿真器,它支持多种Linux发行版的远程连接。Xshell提供了一系列的快捷键,以提高用户的操作效率。以下是一些Xshell中常用的快捷键: 新建会话窗口: Ctrl N 或 Ctrl Shift N 在现有会话中打开新标签&…...

OkGo导入失败解决办法
jcenter()maven { url "https://jitpack.io" }再同步就可以了...

02、pytest环境准备
工具准备 下载Python——python官网下载:https://www.python.org/下载PyCharm——pycharm官网下载:https://www.jetbrains.com.cn/en-us/pycharm/参考文档——pytest官方文档:https://docs.pytest.org/en/7.4.x/一个方便好用的office库——p…...

超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...

stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...

uniapp手机号一键登录保姆级教程(包含前端和后端)
目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号(第三种)后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...