人们普遍接受(我相信!)lock
将强制重新加载字段中的任何值(本质上充当内存屏障或栅栏 - 恐怕我在这方面的术语有点宽松),其结果是字段仅ever在 a 内访问lock
自己不需要volatile
.
(如果我已经错了,请说出来!)
一个很好的评论是在这里长大 https://stackoverflow.com/questions/2430609/c-is-it-possible-to-interrupt-a-specific-thread-inside-a-threadpool/2430684#2430684,质疑如果代码执行以下操作是否同样成立Wait()
- 即一旦它已经Pulse()
d,它是否会从内存中重新加载字段,或者它们可能位于寄存器中(等等)。
或者更简单地说:该字段是否需要volatile
确保在恢复后获得当前值Wait()
?
看着反光镜,Wait
向下调用ObjWait
,即managed internalcall
(与Enter
).
所讨论的场景是:
bool closing;
public bool TryDequeue(out T value) {
lock (queue) { // arbitrary lock-object (a private readonly ref-type)
while (queue.Count == 0) {
if (closing) { // <==== (2) access field here
value = default(T);
return false;
}
Monitor.Wait(queue); // <==== (1) waits here
}
...blah do something with the head of the queue
}
}
显然我可以做到volatile
,或者我可以将其移出,以便我退出并重新进入Monitor
每次它发出脉冲时,但我很想知道是否是必要的.
自从Wait()
方法是释放并重新获取Monitor
锁定,如果lock
执行内存栅栏语义,然后Monitor.Wait()
也会的。
希望能解决您的评论:
的锁定行为Monitor.Wait()
在文档中(http://msdn.microsoft.com/en-us/library/aa332339.aspx http://msdn.microsoft.com/en-us/library/aa332339.aspx),强调补充:
当线程调用Wait时,它会释放对象上的锁并进入对象的等待队列。对象就绪队列中的下一个线程(如果有的话)获取锁并独占使用该对象。所有调用的线程Wait
保留在等待队列中,直到收到来自 Pulse 的信号或PulseAll
,由锁的所有者发送。如果Pulse
发送后,只有位于等待队列头部的线程受到影响。如果PulseAll
发送后,所有正在等待该对象的线程都会受到影响。当接收到信号时,一个或多个线程离开等待队列并进入就绪队列。允许就绪队列中的线程重新获取锁。
当调用线程重新获取对象上的锁时,此方法返回.
如果您询问是否有参考资料lock
/获得Monitor
意味着内存障碍,ECMA CLI 规范 http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-335.pdf说如下:
12.6.5 锁和线程:
获取锁(System.Threading.Monitor.Enter
或进入同步方法)应隐式执行易失性读操作,并释放锁(System.Threading.Monitor.Exit
或离开同步方法)应隐式执行易失性写入操作。参见第 12.6.7 节。
12.6.7 易失性读和写:
易失性读取具有“获取语义”,这意味着读取保证发生在 CIL 指令序列中读取指令之后发生的对内存的任何引用之前。易失性写入具有“释放语义”,这意味着写入保证发生在 CIL 指令序列中写入指令之前的任何内存引用之后。
此外,这些博客文章还有一些可能令人感兴趣的细节:
- http://blogs.msdn.com/jaredpar/archive/2008/01/17/clr-memory-model.aspx http://blogs.msdn.com/jaredpar/archive/2008/01/17/clr-memory-model.aspx
- http://msdn.microsoft.com/msdnmag/issues/05/10/MemoryModels/ http://msdn.microsoft.com/msdnmag/issues/05/10/MemoryModels/
- http://www.bluebytesoftware.com/blog/2007/11/10/CLR20MemoryModel.aspx http://www.bluebytesoftware.com/blog/2007/11/10/CLR20MemoryModel.aspx
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)