[英]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.