可重入函数
- 重入:重复调用,函数被不同的流调用,有可能会出现第一次调用还没返回时就再次进入该函数开始下一次调用。
- 可重入:当程序被多个线程反复执行,产生的结果正确。
- 不可重入:当程序被多个线程反复调用,产生的结果出错。
- 可重入函数:一个函数只访问自己的局部变量或参数。
- 不可重入函数:当函数访问一个全局的变量或者参数时,有可能因为重入而造成混乱。
线程安全
- 线性安全:一个函数当且仅当被多个并发线程反复调用时,它会一直产生正确的结果,被称为线程安全。
可重入特点
- 由于可重入函数多次调用不会出错,因此可重入函数不用担心数据会被破坏。可重入函数任何时候都可以被中断,一段时间后又可以运行,而相应的数据不会丢失。可重入函数只使用局部变量,即保存在CPU寄存器或者堆栈中;或者如果使用全局变量时,则要对全局变量予以保护。
不可重入特点
如果一个函数符合以下条件之一的,则是不可重入的:
- 调用了malloc/free函数,因为malloc函数是用全局链表来管理堆的。
- 调用了标准I/O库函数,标准I/O库的很多实现都以不可重入的方式使用全局数据结构。
- 可重入体内使用了静态的数据结构。
可重入函数和线程安全
可重入函数与线程安全并不相同,一般来说,可重入的函数一定是线程安全的,但反过来不一定成立,关系可有下图解释。
所有函数
可重入函数与线程安全的区别与联系
- 线程安全是在多个线程情况下引发的,而可重入函数可以在只有一个线程的情况下来说。
- 线程安全不一定是可重入的,而可重入函数则一定是线程安全的。
- 如果一个函数中有全局变量,那么这个函数既不是线程安全也不是可重入的。
- 如果将对临界资源的访问加上锁,则这个函数是线程安全的,但如果这个重入函数若锁还未释放则会产生死锁,因此是不可重入的。
- 线程安全函数能够使不同的线程访问同一块地址空间,而可重入函数要求不同的执行流对数据的操作互不影响使结果是相同的。