可重入函数与线程安全

来源:互联网 发布:有公积金借钱软件 编辑:程序博客网 时间:2024/06/18 05:11

可重入函数:
可重入函数主要用于多任务环境中,一个可重入的函数简单来说就是可以被中断的函数,也就是说,可以在这个函数执行的任何时刻中断它,转入OS调度下去执行另外一段代码,而返回控制时不会出现什么错误。
(1)可以在执行的过程中可以被打断;
(2)被打断之后,在该函数一次调用执行完之前,可以再次被调用(或进入,reentered)。
(3)再次调用执行完之后,被打断的上次调用可以继续恢复执行,并正确执行。

可重入函数的特点:
1、不能使用静态变量或者全局变量
2、不能使用malloc或者free
3、不调用不可重入函数
4、不返回静态或全局数据,所有数据都有函数的调用者提供;
如果⼀个函数符合以下条件之一则是不可重⼊入的:
调用了malloc或free,因为malloc也是⽤用全局链表来管理堆的。
调用了标准I/O库函数。标准I/O库的很多实现都以不可重入的方式使用全局数据结构

线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污染。
线程不安全就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据
如何避免这个问题:
1, 减少对临界资源的依赖,尽量避免访问全局变量,静态变量或其它共享资源,如果必须要使用共享资源,所有使用到的地方必须要进行互斥锁 (Mutex) 保护;
2, 线程安全的函数所调用到的函数也应该是线程安全的,如果所调用的函数不是线程安全的,那么这些函数也必须被互斥锁 (Mutex) 保护;

线程安全与可重入函数之间的区别于联系:
1、线程安全是在多线程的情况下引发的,而可重入函数可以再单线程的情况下来看
2、线程安全不一定是可重入的,但是可重入函数一定是线程安全的
3、如果一个函数中有全局变量,那么这个函数一定不是线程安全的,也不是可重入的
4、如果对临界资源进行加锁,那么这个函数一定是线程安全的,但如果是可重入加锁,可能锁未被释放,则会产生死锁因此是不可重入的。
5、线程安全函数能够使不同的线程访问同一块地址空间,而可重入函数要求不同的执行流对数据的操作不影响结果,使结果是相同的。

总体来说:线程安全的范围相对于可重入函数要大,因此线程安全不一定是可重入的,但是可重入函数一定是线程安全的。