Reentrancy (computing)
In computing, a computer program or subroutine is called reentrant if multiple invocations can safely run concurrently. The concept applies even on a single processor system, where a reentrant procedure can be interrupted in the middle of its execution and then safely be called again ("re-entered") before its previous invocations complete execution. The interruption could be caused by an internal action such as a jump or call, or by an external action such as an interrupt or signal. The previous invocations may resume correct execution before the reentered invocation completes, unlike recursion, where the previous invocations may only resume correct execution once the reentered invocation completes.
This definition originates from multiprogramming environments where the flow of control could be interrupted by an interrupt and transferred to an interrupt service routine (ISR) or "handler" subroutine. Any subroutine used by the handler that could potentially have been executing when the interrupt was triggered should be reentrant. Often, subroutines accessible via the operating system kernel are not reentrant. Hence, interrupt service routines are limited in the actions they can perform; for instance, they are usually restricted from accessing the file system and sometimes even from allocating memory.
This definition of reentrancy differs from that of thread-safety in multi-threaded environments. A reentrant subroutine can achieve thread-safety,[1] but being reentrant alone might not be sufficient to be thread-safe in all situations. Conversely, thread-safe code does not necessarily have to be reentrant (see below for examples).
Other terms used for reentrant programs include "pure procedure"[2] or "sharable code".[3] Reentrant subroutines are sometimes marked in reference material as being "signal safe".[4]
若一个程序或子程序可以「在任意时刻被中断然后操作系统调度执行另外一段代码,这段代码又调用了该子程序不会出错」,则称其为可重入(reentrant或re-entrant)的。即当该子程序正在运行时,执行线程可以再次进入并执行它,仍然获得符合設計時預期的结果。与多线程并发执行的线程安全不同,可重入强调对单个线程执行时重新进入同一个子程序仍然是安全的。
可重入概念是在单线程操作系统的时代提出的。一个子程序的重入,可能由于自身原因,如执行了jmp或者call,类似于子程序的递归调用;或者由于操作系统的中断响应。UNIX系统的signal的处理,即子程序被中断处理程序或者signal处理程序调用。所以,可重入也可称作“异步信号安全”。这里的异步是指信号中断可发生在任意时刻。 重入的子程序,按照后进先出线性序依次执行。
若一个函数是可重入的,则该函数应当满足下述条件:
- 不能含有静态(全局)非常量数据。
- 不能返回静态(全局)非常量数据的地址。
- 只能处理由调用者提供的数据。
- 不能依赖于单实例模式资源的锁。
- 调用(call)的函数也必需是可重入的。
上述条件就是要求可重入函数使用的所有变量都保存在呼叫堆疊的当前函数栈(frame)上,因此同一执行线程重入执行该函数时加载了新的函数帧,与前一次执行该函数时使用的函数帧不冲突、不互相覆盖,从而保证了可重入执行安全。
多「用户/对象/进程优先级」以及多进程(Multiple processes),一般会使得对可重入代码的控制变得复杂。同时,IO代码通常不是可重入的,因为他们依赖于像磁盘这样共享的、单独的(類似編程中的靜態、全域)资源。
可重入性是函数编程语言的关键特性之一。