有人可以告诉我哪些代码可以称为“重入”代码?
在阅读一些实时操作系统时,我发现了这个词。为了使代码成为“可重入”代码,必须坚持哪些学科?
答案 0 :(得分:41)
通常,可重入的代码块是在早期调用完成之前可由另一个actor输入的代码块,而不会影响第一个actor通过代码的路径。也就是说,可以在代码已经运行时重新输入代码并仍能产生正确的结果。
在大多数情况下,“actors”是同一进程的线程,但 thread safety 和re-entrant的概念略有不同:并非每个线程安全块都是-entrant,但每个重入块都是线程安全的。也就是说,重新入侵比线程安全更强大。以下是Raymond Chen的 a good example ,其中一段代码可能是线程安全的,但不是可重入的。
当代码是递归时有一种特殊情况:正如Marc Gravell指出的那样,同一个actor在自己的调用完成之前调用代码。所有正确的递归块都是可重入的;当然,并非每个重入块都是递归的。
答案 1 :(得分:10)
John Feminella的回答说:
一个可重入的代码块就是那个 之前可以由另一个演员输入 早期的调用已经完成。 也就是说,可以重新进入 代码已经运行了。
但是对于不可重入的代码块也是如此。如果编写的代码块没有考虑到这个问题,那么第二个actor仍然可以同时输入它。
问题是这对调用的结果有什么影响。更准确地说:一个可重入的块是一个可以在早期调用完成之前由另一个actor输入的块,而不会改变任何一个调用的结果。
两个调用都不应该能够检测到另一个的“存在”。
答案 2 :(得分:9)
实际上,任何类型的递归代码都可以被归类为可重入代码(即,您可以在不完成它的情况下回调到相同的方法),但在讨论锁,互斥锁时,这是使用特别是,信号量等等。例如,如果一旦你有锁就可以重新锁定代码(即你没有自己死锁) - 例如:
public void AddIfNecessary(string s) {
lock(syncObj) {
if(!Contains(s)) Add(s);
}
}
public void Add(string s) {
lock(syncObj) {
list.Add(s);
}
}
public bool Contains(string s) {
lock(syncObj) {
return list.Contains(s);
}
}
这里锁是可重入的事实意味着我们可以调用Contains
和Add
,而不必担心我们已经拥有“独占”锁,使代码更简单。在内部,使用计数器而不是简单的“使用中”标志。
答案 3 :(得分:3)
可重入代码是指页面共享公共资源并且不应更改或操纵资源。然后,此资源称为重入代码或纯代码。
答案 4 :(得分:1)
当第一个线程正在运行时,另一个线程可以调用代码吗?如果代码产生回调函数,回调函数本身可以在第一个runthrough完成之前调用代码吗?
如果代码使用未锁定的全局变量,或者具有自己的静态变量而不采取特殊预防措施,则任何这些情况都可能会破坏它。
答案 5 :(得分:1)
可以由并行运行的不同线程调用的代码。所以,代码:
答案 6 :(得分:0)
如果计算机程序可以在执行过程中被中断,然后在其先前的调用完成执行之前再次安全地调用,则该计算机程序称为可重入。中断可能是由内部操作(如跳转或调用)或外部操作(如硬件中断或信号)引起的。重新进入的调用完成后,之前的调用将恢复正确执行。
答案 7 :(得分:0)
不可重入的例子
class Test {
int count;
// Here method1() is not reentrant
int method1()
{
return count + 1;
}
}
可重入的例子
class Test {
int count;
// Here method1() is reentrant
int method1(int count)
{
return count + 1;
}
}
答案 8 :(得分:0)
简单地说,重入代码是可以在多个进程之间共享的代码。
满足以下条件时可以这样做:
因此,遵循这些条件的代码可以称为可重入代码。