在阅读了测试和设置维基百科条目后,我仍然留下了"测试和设置将用于什么?"的问题.
我意识到你可以使用它来实现Mutex(如维基百科中所述),但它有什么其他用途?
我知道.NET内存模型(在.NET Framework上;不是compact/micro/silverlight/mono/xna/what-have-you)保证对于某些类型(最值得注意的是原始整数和引用)操作保证是原子.
此外,我相信x86/x64测试和设置指令(和Interlocked.CompareExchange
)实际上引用了全局内存位置,因此如果成功,另一个Interlocked.CompareExchange
将看到新值.
最后,我相信volatile
关键字是指令编译器尽快传播读写操作并不重新排序有关此变量的操作(对吗?).
这导致了一些问题:
Interlocked.Read
没有int的重载,只有longs(2个WORD,因此通常不会原子读取).我一直认为.NET内存模型保证在读取整数/引用时会看到最新的值,但是使用处理器缓存,寄存器等等.我开始意识到这可能是不可能的.那么有没有办法强制重新获取变量?如果有两个全局整数变量x和y,则初始化为0,如果我写:
x = 1;
y = 2;
Run Code Online (Sandbox Code Playgroud)
那个NO线程将看到x = 0和y = 2(即写入将按顺序发生).如果它们不稳定,这会改变吗?
Atomic指令是什么意思?
以下内容如何成为Atomic?
检查并设置
int TestAndSet(int *x){
register int temp = *x;
*x = 1;
return temp;
}
Run Code Online (Sandbox Code Playgroud)
从软件的角度来看,如果不想使用非阻塞同步原语,那么如何确保指令的原子性?是否只能在硬件或某些装配级指令优化中使用?
language-agnostic synchronization test-and-set nonblocking atomicity
编译器或处理器可以重新排序以下指令,以便另一个线程看到a == 0
和b == 1
?
假设int a = 0, b = 0;
某个地方.
System.Threading.Interlocked.CompareExchange<int>(ref a, 1, 0);
System.Threading.Interlocked.CompareExchange<int>(ref b, 1, 0);
Run Code Online (Sandbox Code Playgroud) atomic_flag_test_and_set
是的!atomic_flag_clear
是的!atomic_flag_test_and_clear
没有atomic_flag_set
没有如果您想在某些上下文中对事件设置标志,并在其他上下文中检查并清除事件,C/C++ 不允许您在每个上下文中执行单个原子调用。
您必须反转标志,因此清除事件上的标志,在检查事件时检查并设置标志。
没什么大不了的,但在这种情况下似乎是倒退的,特别是考虑到标志的默认状态为 false,这在相反的意义上意味着默认情况下会断言事件。
我想,也可以使用原子bool
with来代替。atomic_exchange
我正在阅读有关测试和设置原子操作的维基百科文章。它说实现互斥的一种方法是使用基于测试和设置的锁。
但是,根据同一篇文章,test-and-set 操作具有有限的共识数,最多可以解决两个并发进程的无等待共识问题。
那么基于 test-and-set 操作的互斥锁是否只对两个线程有效?如果是这样,“实际”互斥是如何实现的?
language-agnostic concurrency multithreading atomic test-and-set
test-and-set ×6
.net ×2
atomic ×2
atomicity ×1
c# ×1
c++ ×1
c11 ×1
concurrency ×1
embedded ×1
mutex ×1
nonblocking ×1
stdatomic ×1
volatile ×1