要解释可重入函数为何物,首先需要区分单线程程序和多线程程序。典型UNIX程序都具有一条执行线程,贯穿程序始终,CPU围绕单条执行逻辑来处理指令。而对于多线程程序而言,同一进程却存在多条独立、并发的执行逻辑流。
如果同一个进程的多条线程可以同时安全的调用某一函数,那么该函数就是可重入的。此处,“安全”意味着,无论其他线程调用该函数的执行状态如何,函数均可产生预期结果。
SUSv3对可重入函数的定义是:函数有两条或多条线程调用时,即便是交叉执行,其效果也与各线程以任意顺序依次调用时一致。
更新全局变量或者静态数据结构的函数可能是不可重入的。(只用到本地变量的函数肯定是可重入的。)
C语言标准函数库中,malloc和free就维护有一个针对已释放内存块的链表,用于从堆中重新分配内存。如果主程序在调用malloc期间为一个同样调用malloc的信号处理器函数所中断,那么该链表可能会遭到破坏。因此,malloc函数族以及使用它们的其他库函数都是不可重入的。
异步信号安全函数是指当信号处理器函数调用时,可以保证其实现是安全的。如果某一函数是可重入的,又或者信号处理器函数无法将其中断时就称该函数是异步信号安全的。
若函数可同时供多个线程安全调用,则称之为线程安全函数;反之,如果函数不是线程安全的,则不能并发调用。
由此可以看出,可重入函数一定是线程安全函数,不可重入函数也可能是线程安全函数,例如,malloc函数是不可重入函数,但是malloc函数通过使用互斥量实现了线程安全。