C# 互斥:这安全吗?

C# 互斥:这安全吗?,c#,.net,multithreading,mutual-exclusion,C#,.net,Multithreading,Mutual Exclusion,这种相互排斥的模式是否像我认为的那样安全?如果是,你怎么称呼它 lock (_lock) { if (_flag) return; else _flag = true; } try { //critical code... } finally { _flag = false; } 我希望确保关键部分,但不要让其他线程堆积起来等待获取锁。很明显,我确保国旗不会被放在其他地方。有更好的方法吗?你看过吗?你看过吗?不,那不安全。如果要确保在不阻塞的情况下互斥,可以使用

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

lock (_lock) {
    if (_flag) return;
    else _flag = true;
}
try {
    //critical code...
}
finally {
    _flag = false;
}

我希望确保关键部分,但不要让其他线程堆积起来等待获取锁。很明显,我确保国旗不会被放在其他地方。有更好的方法吗?

你看过吗?

你看过吗?

不,那不安全。如果要确保在不阻塞的情况下互斥,可以使用Monitor.TryEnter:

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

不,那不安全。如果要确保在不阻塞的情况下互斥,可以使用Monitor.TryEnter:

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

一个简单的
lock(Object)
语句不起作用吗?在幕后,它创建了
监视器
try中的关键部分。。。最后
block

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

一个简单的
lock(Object)
语句不起作用吗?在幕后,它创建了
监视器
try中的关键部分。。。最后
block

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

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

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

if(_flag) return;

这两个关于模式为何会失败的例子都是高度推测性的,我认为你可以放心地假设它会起作用。但是,如果有另一个选项可以根据需要工作,那么最好使用它(参见其他帖子)。如果在同一代码中有其他开发人员,则不需要考虑该模式是否有效。

< P>互斥模式的正确性取决于赋值α旗号=假原子。想象一下,如果任务被另一个线程中断,会发生什么。如果测试可以将赋值的中间结果解释为false,那么一个赋值可能会导致多个线程进入临界部分

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

if(_flag) return;

这两个关于模式为何会失败的例子都是高度推测性的,我认为你可以放心地假设它会起作用。但是,如果有另一个选项可以根据需要工作,那么最好使用它(参见其他帖子)。如果在同一代码中有其他开发人员,他们不需要考虑该模式是否有效。

这很好,我将使用TryEnter,但是你能解释一下上面的不安全吗?谢谢。你正在访问锁外的标志。事实上,您只是将其设置为false,但这意味着您可能会拒绝一个基本线程-我可以预见问题。因为使用TryEnter相对比较容易,所以我会使用它…那很好,我会使用TryEnter,但是你能解释一下上面的内容是如何不安全的吗?谢谢。你正在访问锁外的标志。事实上,您只是将其设置为false,但这意味着您可能会拒绝一个基本线程-我可以预见问题。因为使用TryEnter相对容易,所以我会使用它…“但是没有其他线程堆积起来等待获取锁。”-也就是说,OP希望它相互排斥但不阻塞。这是一个有趣的要求。我从来都不需要这样的锁定机制。“但是没有其他线程堆积起来等待获取锁。”-也就是说,OP希望它相互排斥但不阻塞。这是一个有趣的要求。我从来都不需要这样的锁定机制。回答很有趣,谢谢!我没有考虑优化的效果。有趣的回答,谢谢!我没有考虑优化的效果。