Sca*_*ark 6 c++ multithreading
这是我的头脑.
我正在尝试实现一些"无锁"代码并使用CAS(gcc __sync_val_compare_and_swap)来解决这个问题.
我的问题可以通过以下代码显示.
volatile bool lock;
void *locktest( void *arg )
{
for ( int i = 0 ; i < 100000 ; ++i )
{
// acquire a lock
while( __sync_val_compare_and_swap( &lock, false, true ) == true )
{
// Spin while we don't acquire
}
// make sure we have the lock
assert( lock == true );
// release the lock
assert( __sync_val_compare_and_swap( &lock, true, false ) == true );
}
}
Run Code Online (Sandbox Code Playgroud)
好吧,如果我在10个并发线程中运行上面的代码,一切都很好.
但是,如果我将代码更改为read
// acquire a lock
while( __sync_val_compare_and_swap( &lock, lock, true ) == true )
Run Code Online (Sandbox Code Playgroud)
请注意,我已将"false"更改为"lock".
一切都破裂了,断言了
// make sure we have the lock
assert( lock == true );
Run Code Online (Sandbox Code Playgroud)
火灾.任何人都可以解释为什么这会有所作为?
谢谢马克.
在我看来,__sync_val_compare_and_swap
总是会返回变量的旧值,即使没有发生交换.在这种情况下,假设另一个线程在您尝试获取之前持有锁 - 那么这lock
是真的,并且您正在调用__sync_val_compare_and_swap(&lock, true, true);
.就在实际的原子比较和交换之前(但在确定了函数参数之后),另一个线程释放锁 - lock
变为false.在compare_and_swap
随后将返回false,但没有进行swap
操作,因为它比较值是不是在锁定的值.这个线程没有执行交换,所以lock
剩下的值false
,触发你的断言.
顺便说一下,我强烈建议制作lock
一个volatile bool
.您不希望编译器优化对此类变量的引用.