什么是重入程序?

Posted

技术标签:

【中文标题】什么是重入程序?【英文标题】:What is a Re-entrant procedure? 【发布时间】:2011-10-24 22:44:39 【问题描述】:

什么是可重入程序,您能否举例说明何时使用它?

编辑:另外,多个进程可以并行访问重入过程吗?

请提供与***不同的解释方式,因为我不完全理解他们的描述,因此我的问题 here

【问题讨论】:

【参考方案1】:

可重入过程是一种程序代码的单个副本可以在同一时间段内由多个用户共享的过程。重新进入有两个关键方面:程序代码不能自行修改,每个用户的本地数据必须单独存储。

在共享系统中,可重入允许更有效地使用主内存:程序代码的一份副本保存在主内存中,但多个应用程序可以调用该过程。因此,一个可重入过程必须有一个永久部分(构成该过程的指令)和一个临时部分(一个指向调用程序的指针以及程序使用的局部变量的内存)。

过程的每个执行实例(称为激活)都将执行永久部分中的代码,但必须有自己的局部变量和参数副本。与特定激活关联的临时部分称为激活记录。

支持可重入过程最方便的方法是通过堆栈。当调用可重入过程时,激活记录成为过程调用时创建的堆栈帧的一部分

【讨论】:

【参考方案2】:

它是一个子程序,可以在它已经激活时调用。例如,递归函数通常是可重入的。从信号处理程序调用的函数也必须是可重入的。可重入函数是线程安全的,但并非所有线程安全的函数都是可重入的。

【讨论】:

递归函数不一定是可重入的。例如:int fact(int x) static int tmp = fact(x-1); return x>1 ? x*tmp : 1; @R...,按照我的同意进行了更改,但您的示例有问题(静态变量仅在第一次调用时初始化)。 抱歉,我懒得尝试将其放入评论中。正确的版本是:int fact(int x) static int tmp; tmp = fact(x-1); return x>1 ? x*tmp : 1; @AProgrammer,static 存储持续时间的变量在第一次调用之前初始化,通常在编译时或某些情况下在程序启动时。【参考方案3】:

重入背后的想法是,可以在例程已经在执行的过程中调用它,并且它仍然可以正常工作。

通常这是通过它仅使用在堆栈上声明的参数和局部变量来实现的(在 C 术语中,没有static locals)。在执行期间不要锁定任何全局资源也很重要。

现在,您可能会问:“例程一次运行多次这样奇怪的事情怎么会发生?”嗯,这可能发生的一些方式是:

例程是递归的(或与其他一些例程相互递归)。 它被另一个线程调用。 它被中断调用。

如果其中任何一种发生,并且例程正在修改全局(或 C static 本地),那么新的执行可能会消除第一次执行所做的更改。例如,如果将该全局变量用作循环控制变量,它可能会导致第一次执行,当它最终恢复时,循环错误的次数。

【讨论】:

请注意,您的情况(2)不需要重入操作系统(它被另一个线程调用)。对于这种情况,锁定总是足够的,因为任何一个线程都可以独立进行。递归调用和来自信号处理程序的调用的不同之处在于,在“内部”调用返回之前,“外部”调用无法进行。 请注意,通过使用线程本地存储,非重入函数可以是线程安全的。

以上是关于什么是重入程序?的主要内容,如果未能解决你的问题,请参考以下文章

并发编程:不得不说的ReentrantLock

9AQS实现重入锁

9AQS实现重入锁

线程安全与可重入函数之间的区别

Synchronized 与 ReentrantLock 的区别!

Java多线程——ReentrantLock源码阅读