相互排斥:这安全吗?
这种互斥模式是否像我想象的那样安全? 如果是这样,你怎么称呼它?
lock (_lock) {
if (_flag) return;
else _flag = true;
}
try {
//critical code...
}
finally {
_flag = false;
}
我想确保关键部分,但没有其他线程堆积等待获取锁。 显然我确保该标志没有设置在其他地方。 有没有更好的办法?
Is this pattern for mutual exclusion as safe as I think it is? If so, what do you call it?
lock (_lock) {
if (_flag) return;
else _flag = true;
}
try {
//critical code...
}
finally {
_flag = false;
}
I want to ensure the critical section, but without the other threads piling up waiting to acquire the lock. Obviously I make sure the flag is set nowhere else. Is there a better way?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
不,那不安全。 如果想保证互斥而不阻塞,可以使用Monitor.TryEnter:
No, that is not safe. If you want to ensure mutually exclusive without blocking, you can use Monitor.TryEnter:
您是否查看过
Monitor.TryEnter
?Have you looked at
Monitor.TryEnter
?互斥模式的正确性取决于赋值 _flag=false 是原子的。 想象一下如果分配可能被另一个线程中断会发生什么。 如果测试可以将赋值的中间结果解释为 false,则一项赋值可能会导致多个线程进入临界区。
互斥模式的正确性还取决于编译器中是否存在可能重新排列语句顺序的优化。 想象一个“智能”编译器会将赋值 _flag=false 向上移动,因为中间的代码中没有引用 _flag (并且中间的代码不会引发异常)。 然后,编译器可以优化锁定部分中的部分以读取
模式可能失败的两个示例都是高度推测性的,我认为您可以安全地假设它有效。 但是,如果存在另一个可以根据需要工作的选项,您最好使用它(请参阅其他帖子)。 如果有其他开发人员使用相同的代码,他们不需要考虑该模式是否有效。
The correctness of your mutual exclusion pattern depends on the assignment _flag=false being atomic. Imagine what would happen if the assignment could be interrupted by another thread. If intermediate results of the assignment could be interpreted as false by the test, one assignment could cause several threads to enter the critical section.
The correctness of the mutual exclusion pattern also depends on the absence of optimisations in the compiler that may rearrange the ordering of the statements. Imagine a "smart" compiler that would move the assignment _flag=false up, because _flag is not referred to in the code that is in between (and the code in between does not throw exceptions). The compiler could then optimise the part in the lock section to read
Both examples of why the pattern could fail are highly speculative and I think that you are safe in assuming it works. However, in the presence of another option that works as required, you're better off using that (see the other posts). If there are other developers in the same code, they do not need to consider whether the pattern works.
简单的
lock(Object)
语句不起作用吗? 在幕后,它在try...finally
块内创建Monitor
和关键部分。Wouldn't a simple
lock(Object)
statement work? Behind the scenes, it creates theMonitor
and critical section inside atry... finally
block.