对比线程安全和可重入函数

本文探讨了可重入函数和线程安全的概念。可重入函数允许在执行过程中被中断并重新进入,而线程安全的函数则是在多线程环境下能正确运行并保证数据安全。虽然可重入函数一定是线程安全的,但线程安全的函数并不一定是可重入的。两者之间的关系、区别和转换方法也进行了详细说明。
摘要由CSDN通过智能技术生成

可重入函数:

1.定义:

可重入函数:可以被两个或多个执行流进入的函数,并且产生的结果是正确的,可以在函数执行的任何时候中断它,它主要用于多任务环境。

不可重入函数:因为重入而导致错误的函数称为不可重入函数。

2.不可重入的条件(只要满足一下其中任意一个条件就不可重入):

(1)函数内使用了静态数据结构;

(2)函数内调用了malloc(),free();

(3)函数内部调用了标准输入,标准输出;

3.编写可重入函数的规则:

(1)尽量使用局部变量,不要使用全局变量,如果必须访问全局变量时,要利用互斥信号量来保护全局变量;

(2)和硬件发生交互时,要关闭硬件中断;

(3)不调用任何不可重入的函数;

(4)使用堆栈时要谨慎;

用例子来证明一下:


main函数调用insert函数向一个链表head中插入节点node1,插入操作分为两步,刚做完第一步的时候,因为硬件中断使进程切换到内核,再次回用户态之前检查到有信号待处理,于是切换到sighandler函数,sighandler也调用insert函数向同一个链表head中插入节点node2,插入操作的两步都做完之后从sighandler返回内核态,再次回到用户态就从main函数调用的insert函数中继续往下执行,先前做第一步之后被打断,现在继续做完第二步。结果是,main函数和sighandler先后 向链表中插入两个节点,而最后只有一个节点真正插入链表中了。

insert函数被不同的控制流程调用,有可能在第一次调用还没返回时就再次进入该函 数,这称为重入,insert函数访问一个全局链表,有可能因为重入而造成错乱,像这样的函数称为不可重入函数。

线程安全

1.定义:

线程安全即多线程访问时,采用加锁机制,在线程访问类中的数据时,进行了数据保护;

2.如果一个函数能安全的同时被多个线程调用,并得到正确的结果,那么这个函数就是线程安全的;

3.所有导致结果不正确的因素,都是不安全的调用;

4.线程的安全问题一般是由全局变量和静态变量引起的;

5.线程安全不要求调用的函数结果具有可再现性;

6.如何避免线程不安全问题:

若每个线程对全局变量、静态变量只有读操作,那么这个全局变量是线程安全的,如果同时对它执行写操作,必须要考虑线程同步,负责影响线程安全

7.我们将线程不安全函数分为四种类型(有交叉):

①不保护共享变量的函数

②保持跨越多个调用的状态函数

③返回指向静态变量指针的函数

④调用线程不安全函数的函数

可重入函数与线程安全的区别联系

由可重入函数和线程安全的特点可以知道:

1.可重入函数一定是线程安全的,但线程安全不一定是可重入的;

2.可重入函数和线程安全都与全局变量有关;

3.当对临界资源的访问加锁保护时,函数时线程安全的,但对可重入函数加锁后没有释放锁时,会造成死锁,变为不可重入;

4.可重入函数强调不同执行流对数据的操作互不影响,而且结果相同,但是线程安全允许在调用该函数时,出现互相影响的情况,只要使用互斥锁保证安全性即可;

5.对于一个不可重入函数,可以通过互斥锁让它安全的被多个线程同时调用,那么这个不可重入函数转换成为了线程安全;

下面呢我用一张图表示他们间明显的关系:












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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值