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

smw*_*dia 25 operating-system

有人能告诉我哪些代码可以被称为"重入"代码?

我在阅读一些实时操作系统时遇到过这个词.为了使代码成为"可重入"代码,必须坚持哪些学科?

Joh*_*lla 41

通常,可重入的代码块是在早期调用完成之前可由另一个actor输入的代码块,而不会影响第一个actor通过代码的路径.也就是说,可以在代码已经运行时重新输入代码并仍能产生正确的结果.

在大多数情况下,"actors"是同一进程的线程,但线程安全和重入的概念略有不同:并非每个线程安全块都是可重入的,但每个重入块都是线程安全的.也就是说,重新入侵比线程安全更强大.这是一个很好的例子,来自Raymond Chen,一个代码块可能是线程安全的,但不是可重入的.

当代码是递归时有一个特例:正如Marc Gravell指出的那样,同一个actor在自己的调用完成之前调用代码.所有正确的递归块都是可重入的; 当然,并非每个重入块都是递归的.

  • _"......但是每个重入的块都是线程安全的."_你能不能看一下[维基百科关于重入的条目](http://en.wikipedia.org/wiki/Reentrancy_%28computing%29 )?因为有一个函数的例子是可重入但不是线程安全的.编辑是否可能犯了错误?谢谢. (2认同)

Dan*_*ker 10

John Feminella的回答是:

可重入的代码块是在早期调用完成之前可由另一个actor输入的代码块.也就是说,可以在代码已经运行时重新输入代码.

但是对于不可重入的代码块也是如此.如果在不考虑此问题的情况下编写了代码块,则第二个actor仍然可以同时输入它.

问题是这对调用的结果有什么影响.更准确地说:重入块是在早期调用完成之前可以由另一个actor输入的块,而不会更改任一调用的结果.

调用都不应该能够检测到另一个的"存在".

  • 直到现在我才注意到这个答案!谢谢你的澄清; 你是对的,我可以更具体.我会相应修改. (2认同)

Mar*_*ell 9

事实上,任何类型的递归代码都可以归类为可重入代码(即,您可以在不完成它的情况下回调到相同的方法),但这在使用锁,互斥体,信号量等时特别使用.例如,锁是重新-entrant如果你有锁,你可以再次成功"锁定"代码(即你没有自己死锁) - 例如:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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