相互排斥:这安全吗?

发布于 2024-07-13 21:35:54 字数 260 浏览 9 评论 0原文

这种互斥模式是否像我想象的那样安全? 如果是这样,你怎么称呼它?

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

沙与沫 2024-07-20 21:35:54

不,那不安全。 如果想保证互斥而不阻塞,可以使用Monitor.TryEnter:

if (Monitor.TryEnter(lockObj, 0)) {
    // got the lock !
    try {
        // code
    }
    finally { // release the lock
        Monitor.Exit(lockObj);
    }
}

No, that is not safe. If you want to ensure mutually exclusive without blocking, you can use Monitor.TryEnter:

if (Monitor.TryEnter(lockObj, 0)) {
    // got the lock !
    try {
        // code
    }
    finally { // release the lock
        Monitor.Exit(lockObj);
    }
}
提笔书几行 2024-07-20 21:35:54

您是否查看过 Monitor.TryEnter

Have you looked at Monitor.TryEnter?

风吹过旳痕迹 2024-07-20 21:35:54

互斥模式的正确性取决于赋值 _flag=false 是原子的。 想象一下如果分配可能被另一个线程中断会发生什么。 如果测试可以将赋值的中间结果解释为 false,则一项赋值可能会导致多个线程进入临界区。

互斥模式的正确性还取决于编译器中是否存在可能重新排列语句顺序的优化。 想象一个“智能”编译器会将赋值 _flag=false 向上移动,因为中间的代码中没有引用 _flag (并且中间的代码不会引发异常)。 然后,编译器可以优化锁定部分中的部分以读取

if(_flag) return;

模式可能失败的两个示例都是高度推测性的,我认为您可以安全地假设它有效。 但是,如果存在另一个可以根据需要工作的选项,您最好使用它(请参阅其他帖子)。 如果有其他开发人员使用相同的代码,他们不需要考虑该模式是否有效。

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

if(_flag) return;

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.

挽你眉间 2024-07-20 21:35:54

简单的 lock(Object) 语句不起作用吗? 在幕后,它在 try...finally 块内创建 Monitor 和关键部分。

private static readonly Object lockMe = new Object();
lock(lockMe)
{
    // critical code
}

Wouldn't a simple lock(Object) statement work? Behind the scenes, it creates the Monitor and critical section inside a try... finally block.

private static readonly Object lockMe = new Object();
lock(lockMe)
{
    // critical code
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文