Joh*_*lla 41
通常,可重入的代码块是在早期调用完成之前可由另一个actor输入的代码块,而不会影响第一个actor通过代码的路径.也就是说,可以在代码已经运行时重新输入代码并仍能产生正确的结果.
在大多数情况下,"actors"是同一进程的线程,但线程安全和重入的概念略有不同:并非每个线程安全块都是可重入的,但每个重入块都是线程安全的.也就是说,重新入侵比线程安全更强大.这是一个很好的例子,来自Raymond Chen,一个代码块可能是线程安全的,但不是可重入的.
当代码是递归时有一个特例:正如Marc Gravell指出的那样,同一个actor在自己的调用完成之前调用代码.所有正确的递归块都是可重入的; 当然,并非每个重入块都是递归的.
Dan*_*ker 10
John Feminella的回答是:
可重入的代码块是在早期调用完成之前可由另一个actor输入的代码块.也就是说,可以在代码已经运行时重新输入代码.
但是对于不可重入的代码块也是如此.如果在不考虑此问题的情况下编写了代码块,则第二个actor仍然可以同时输入它.
问题是这对调用的结果有什么影响.更准确地说:重入块是在早期调用完成之前可以由另一个actor输入的块,而不会更改任一调用的结果.
调用都不应该能够检测到另一个的"存在".
事实上,任何类型的递归代码都可以归类为可重入代码(即,您可以在不完成它的情况下回调到相同的方法),但这在使用锁,互斥体,信号量等时特别使用.例如,锁是重新-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不必担心我们已经拥有"独占"锁,使代码更简单.在内部,使用计数器而不是简单的"使用中"标志.