可重入函数,不可重入函数与线程安全

来源:互联网 发布:淘宝卖家怎么发文件 编辑:程序博客网 时间:2024/05/29 09:16

•概念

重入:即重复调用,函数被不同的流调用,有可能会出现第一次调用还没返回时就再次进入该函数开始下一次调用。

可重入:当程序被多个线程反复执行,产生的结果正确。

如果一个函数只访问自己的局部变量或参数,称为可重入函数。

不可重入:当程序被多个线程反复调用,产生的结果出错。

当函数访问一个全局的变量或者参数时,有可能因为重入而造成混乱,像这样的函数称为不可重入函数。

主要用于多任务环境中,一个可重入的函数简单来说就是可以被中断的函数,也就是说,可以在这个函数执行的任何时刻中断它,转入OS调度下去执行另外一段代码,而返回控制时不会出现什么错误;

而不可重入的函数由于使用了一些系统资源,比如全局变量区,中断向量表等,所以它如果被中断的话,可能会出现问题,这类函数是不能运行在多任务环境

重入即表示重复进入,首先它意味着这个函数可以被中断,其次意味着它除了使用自己栈上的变量以外不依赖于任何环境(包括static)



      线性安全:一般来说,一个函数被称为线程安全的,当且仅当被多个并发线程反复调用时,它会一直产生正确的结果。

       线程安全函数:在C语言中局部变量是在栈中分配的,任何未使用静态数据或其他共享资源的函数都是线程安全的。
                     使用全局变量的函数是非线程安全的。
                     使用静态数据或其他共享资源的函数,必须通过加锁的方式来使函数实现线程安全。

       线程安全的(Thread-Safe):
                   如果一个函数在同一时刻可以被多个线程安全地调用,就称该函数是线程安全的。
                   线程安全函数解决多个线程调用函数时访问共享资源的冲突问题。


可重入函数编写规范为:

1、不在函数内部使用静态或全局数据 
2、不返回静态或全局数据,所有数据都由函数的调用者提供。 
3、使用本地数据,或者通过制作全局数据的本地拷贝来保护全局数据。
4、如果必须访问全局变量,利用互斥机制来保护全局变量。
5、不调用不可重入函数。


•可重入特点

由于可重入函数多次调用不会出错,因此可重入函数不用担心数据会被破坏。可重入函数任何时候都可以被中断,一段时间后又可以运行,而相应的数据不会丢失。可重入函数只使用局部变量,即保存在CPU寄存器或者堆栈中;或者如果使用全局变量时,则要对全局变量予以保护。

•不可重入特点

如果一个函数符合以下条件之一的,则是不可重入的:

(1)调用了malloc/free函数,因为malloc函数是用全局链表来管理堆的。

(2)调用了标准I/O库函数,标准I/O库的很多实现都以不可重入的方式使用全局数据结构。

(3)可重入体内使用了静态的数据结构。

(4) 函数是singleton中的成员函数而且使用了不使用线程独立存储的成员变量 


•可重入与线程安全

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

(1)线程安全是在多个线程情况下引发的,而可重入函数可以在只有一个线程的情况下来说。

(2)线程安全不一定是可重入的,而可重入函数则一定是线程安全的。

(3)如果一个函数中有全局变量,那么这个函数既不是线程安全也不是可重入的。

(4)如果将对临界资源的访问加上锁,则这个函数是线程安全的,但如果这个重入函数若锁还未释放则会产生死锁,因此是不可重入的。

(5)线程安全函数能够使不同的线程访问同一块地址空间,而可重入函数要求不同的执行流对数据的操作互不影响使结果是相同的。




0 0
原创粉丝点击