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

可重入函数

函数被不同的控制流程调用,有可能在第一次调用还没返回时就再次 进入该函数,这称为重入。
然而有可能因为重入而造成错乱,像这样 的函数称为不可重入函数,
反之,如果一个函数只访问自己的局部变量或参数,则称为可重入 (Reentrant) 函数。
可重入函数:
重入即表示重复进入,首先它意味着这个函数可以被中断,其次意味着它除了使用自己栈上的变量以外不依赖于任何环境(包括static),这样的函数就是purecode(纯代码)可重入,可以允许有多个该函数的副本在运行,由于它们使用的是分离的栈,所以不会互相干扰。如果确实需要访问全局变量(包括static),一定要注意实施互斥手段。可重入函数在并行运行环境中非常重要,但是一般要为访问全局变量付出一些性能代价。
满足下列条件的函数多数是不可重入的:
1) 函数体内使用了静态的数据结构;
2) 函数体内调用了malloc()或者free()函数;
3) 函数体内调用了标准I/O函数。
编写可重入函数:
1、不能在函数内部使用静态或全局数据
2、不能返回静态或全局数据,所有数据都有函数的调用者提供
3、使用本地数据、或通过制作全局数据的本地拷贝来保护全局数据。
4、如果必须访问全局变量,利用互斥机制来保护全局变量。
5、不在可重入函数内部调用不可重入函数。、
6、不调用malloc和free函数,因为malloc是用全局链表来管理堆的。
7、不调用了标准I/O函数。标准I/O函数很多都以不可重入的方式实现全局数据结构。
注意: 最常见的就是在信号处理函数中不能使用不可重入函数。如果在信号处理函数中使用了不可重入函数,则可能导致程序出现错误甚至崩溃。
线程

线程安全

当一个函数被多个线程反复调用的时候,他会一直产生正确的结果,那么这个函数就是线程安全的。线程安全函数解决了多个线程调用函数时访问临界资源的冲突问题。
线程安全函数时,要注意两点:

1, 减少对临界资源的依赖,尽量避免访问全局变量,静态变量或其它共享资源,如果必须要使用共享资源,所有使用到的地方必须要进行互斥锁 (Mutex) 保护;
2, 线程安全的函数所调用到的函数也应该是线程安全的,如果所调用的函数不是线程安全的,那么这些函数也必须被互斥锁 (Mutex) 保护;

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

线程安全的根源就在于”共享数据”。所以不共享任何数据的函数(可重入函数)肯定是线程安全的。但是,即使有共享数据,线程安全还可以通过同步与互斥来保证,所以线程安全并不一定是可重入的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值