c# - Interlocked 用于递增/模拟 bool 值,这安全吗?

标签 c# multithreading interlocked

我只是想知道一位开发人员(已经离开)的这段代码是否可以,我认为他想避免加锁。这与仅使用直接锁定之间是否存在性能差异?

    private long m_LayoutSuspended = 0;
    public void SuspendLayout()
    {
        Interlocked.Exchange(ref m_LayoutSuspended, 1);
    }

    public void ResumeLayout()
    {
        Interlocked.Exchange(ref m_LayoutSuspended, 0);
    }

    public bool IsLayoutSuspended
    {
        get { return Interlocked.Read(ref m_LayoutSuspended) != 1; }
    }

我在想用锁做这样的事情会更容易吗?它确实会被多个线程使用,因此决定使用锁定/互锁的原因。

最佳答案

是的,从到达 m_LayoutSuspended 字段的竞争角度来看,您正在做的事情是安全的,但是,如果代码执行以下操作,则需要锁定,原因如下:

if (!o.IsLayoutSuspended)  // This is not thread Safe .....
{
  o.SuspendLayout();   // This is not thread Safe, because there's a difference between the checck and the actual write of the variable a race might occur.
  ...
  o.ResumeLayout();
} 

一种更安全的方法,它使用 CompareExchange 来确保没有发生竞争条件:

private long m_LayoutSuspended = 0;
public bool SuspendLayout()
{
    return Interlocked.CompareExchange(ref m_LayoutSuspended, 1) == 0;
}

if (o.SuspendLayout()) 
{
  ....
  o.ResumeLayout();
}

或者更好的是简单地使用锁。

关于c# - Interlocked 用于递增/模拟 bool 值,这安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1389426/

相关文章:

c# - 使用线程和 MVVM 将高速数据流式传输到 WPF UI

c# - 在 C# 上测试并发循环缓冲区的好例子

c# - 用于累积 list<list<double>> 中的值的代码的并行版本

concurrency - 联锁平均值 (CAS) 不适用于 HLSL

c++ - 为什么 InterlockedAdd 在 vs2010 中不可用?

c# - Winforms:具有数千个用户控件的可滚动 FlowLayoutPanel - 如何防止内存泄漏并以正确的方式处理对象?

c# - 从控件子类化 ParentForm WndProc

c# - 如何使用 Dapper 检查空值

c# - 如何在代码隐藏中使用 SqlDataAdapter?

multithreading - 如何确保锁定顺序以避免死锁?