线程安全和可重入函数

线程安全:
如果代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和 单线程运行的结果是一样的,而且其他的 变量的值也和预期的是一样的,就是线程安全的。
在单线程运行的情况下,如果Size=0,添加一个元素后,此元素在位置0,而且Size=1;而如果是在多线程情况下,比如有两个线程,线程A先将元素1存放在位置0。但是此时CPU调度线程A暂停,线程B得到运行的机会。线程B向此ArrayList添加元素2,因为此时Size仍然等于0(注意,我们假设的是添加一个元素是要两个步骤,而线程A仅仅完成了步骤1),所以线程B也将元素存放在位置0。然后线程A和线程B都继续运行,都增加Size的值,结果Size都等于1。那好,我们来看看ArrayList的情况,期望的元素应该有2个,而实际元素是在0位置,造成丢失元素,故Size等于1。这就是“线程不安全”了。
可重入函数:
什么是可重入性
重入一般可以理解为一个函数在同时多次调用,例如操作系统在进程调度过程中,或者单片机、处理器等的中断的时候会发生重入的现象。
可重入的函数必须满足以下三个条件:
1、可以在执行的过程中可以被打断;
2、被打断之后,在该函数一次调用执行完之前,可以再次被调用(或进入,reentered)。
3、再次调用执行完之后,被打断的上次调用可以继续恢复执行,并正确执行。
可重入函数可以在任意时刻被中断,稍后再继续运行,不会丢失数据。不可重入(non-reentrant)函数不能由超过一个任务所共享,除非能确保函数的互斥(或者使用信号量,或者在代码的关键部分禁用中断)。
常见的不可重入函数有:
printf ——–引用全局变量stdout
malloc ——–全局内存分配表
free ——–全局内存分配表
不可重入函数的原因在于:
1、 已知它们使用静态数据结构
2、 它们调用malloc和free.
因为malloc通常会为所分配的存储区维护一个链接表,而插入执行信号处理函数的时候,进程可能正在修改此链接表。
3、 它们是标准IO函数.
因为标准IO库的很多实现都使用了全局数据结构
可重入与线程安全
可重入的定义源于单线程环境。在单线程环境下,一段代码在执行中可能被硬件中断,并转而调用中断服务程序(ISR)。在本次调用中断处理函数之前,有可能中断处理函数已经在执行。因此,任何中断处理函数都应该是可重入的。
线程安全的概念则源自于多线程环境。可见,他们的起源是不一样的。那么,他们没有什么必然关系呢。可总结如下:
(1)一个线程安全的函数不一定是可重入的;
(2)一个可重入的函数也不一定是线程安全的!
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值