繁体   English   中英

C#中的非阻塞线程安全布尔标志

[英]Non-blocking thread-safe boolean flag in C#

我想创建在32位和64位系统上都是线程安全且非阻塞的布尔标志。 该解决方案是否满足这两个要求? 如果没有,那会怎样?

public bool Flag {
    get {
        return Interlocked.Read( ref _flag ) == 1;
    }
    set {
        if ( value ) {
            // set flag to "true" if it's false
            Interlocked.CompareExchange( ref _flag, 1, 0 );
        }
        else {
            // set flag to "false" if it's true
            Interlocked.CompareExchange( ref _flag, 0, 1 );
        }
    }
}
private Int32 _flag;

(编辑)以使用Int32 @ M.kazemAkhgary

示例: 3个计时器,在此示例中,每个计时器都有故意重叠的刻度间隔。 2个计时器回调正在读取该标志。 1个计时器回调读取和写入标志。

// Inline function
void Callback( object msg ) {
    if ( Flag ) Debug.WriteLine( (string) msg );
}

// Checks Flag
var timer1 = new Timer( 
    Callback,
    "Tick", // callback arg
    0,      // start timer now
    100     // callback interval ms
);

// Checks Flag
var timer2 = new Timer( 
    Callback, 
    "Tock", // callback arg
    0,      // start timer now
    20      // callback interval ms
);

// Toggles Flag every second
var timer3 = new Timer( 
    _ => {
        Flag = !Flag;
    }, 
    null, // callback arg
    0,    // start timer now
    1000  // callback interval ms
);

您已经关闭,但请查看CompareExchange上的MSDN文档: https ://msdn.microsoft.com/zh-cn/library/801kt583(v = vs.110).aspx

首先,可以使用int而不是Int64来保留标志的状态,并且读取int是原子操作。 仅在32位计算机上读取Int64不是原子的。

您的代码应类似于:(我尚未测试过)

public bool Flag {
get {
    return _flag == 1; // no Interlocked.Read here, reading an int from memory is an atomic operation
}
set {
    if ( value ) {
        // set flag to "true" if it's false

        int newFlagValue = 1;
        int initialFlagValue;
        do {
        // Save the current flag value in a local variable.
        initialFlagValue = _flag; 
        } while (initialFlagValue != Interlocked.CompareExchange(
            ref _flag, newFlagValue, initialFlagValue));            
    }
    else {
        // similar as above.
    }
}
}
private int _flag;

更新:

关于volatile的使用,它有很多未使用的地方,所以我会尽量避免使用它。 检查一下这篇很棒的文章: 何时在C#中使用volatile关键字?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM