什么样的代码可以称为“重入”?

时间:2010-02-16 16:06:59

标签: operating-system

有人可以告诉我哪些代码可以称为“重入”代码?

在阅读一些实时操作系统时,我发现了这个词。为了使代码成为“可重入”代码,必须坚持哪些学科?

9 个答案:

答案 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);
    }
}

这里锁是可重入的事实意味着我们可以调用ContainsAdd,而不必担心我们已经拥有“独占”锁,使代码更简单。在内部,使用计数器而不是简单的“使用中”标志。

答案 3 :(得分:3)

可重入代码是指页面共享公共资源并且不应更改或操纵资源。然后,此资源称为重入代码或纯代码。

答案 4 :(得分:1)

当第一个线程正在运行时,另一个线程可以调用代码吗?如果代码产生回调函数,回调函数本身可以在第一个runthrough完成之前调用代码吗?

如果代码使用未锁定的全局变量,或者具有自己的静态变量而不采取特殊预防措施,则任何这些情况都可能会破坏它。

答案 5 :(得分:1)

可以由并行运行的不同线程调用的代码。所以,代码:

  1. 可以拥有局部变量(在每个线程的堆栈上分配)
  2. 应该保护全局变量和静态变量,因为线程将共享它们并且这里会出现竞争条件。

答案 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)

简单地说,重入代码是可以在多个进程之间共享的代码。

满足以下条件时可以这样做:

  1. 它不应该包含全局和静态数据。
  2. 不应修改它自己的代码。
  3. 不应该调用另一个可重入函数或代码段。
  4. 因此,遵循这些条件的代码可以称为可重入代码。