G ++ CAS(__sync_val_compare_and_swap)问题需要解释

时间:2010-01-26 15:57:07

标签: 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 );
    }
}

好的,如果我在10个并发线程中运行上面的代码,一切都很好。

但是,如果我将代码更改为

        // acquire a lock
        while( __sync_val_compare_and_swap( &lock, lock, true ) == true )

注意我已将“false”更改为“lock”。

所有地狱都破裂了,断言

        // make sure we have the lock
        assert( lock == true );

触发。任何人都可以解释为什么会有所作为吗?

THX 标记

1 个答案:

答案 0 :(得分:5)

在我看来,__sync_val_compare_and_swap将始终返回变量的旧值,即使没有发生交换。在这种情况下,假设另一个线程在您尝试获取锁之前持有锁 - 然后lock为真,并且您正在调用__sync_val_compare_and_swap(&lock, true, true);。在实际的原子比较和交换之前(但在确定了函数参数之后),另一个线程释放锁 - lock变为false。然后compare_and_swap将返回false,但不会执行swap操作,因为它与之比较的值不是锁中的值。此线程未执行交换,因此lock的值仍为false,从而触发您的断言。

顺便说一下,我强烈建议lockvolatile bool。您不希望编译器优化对这些变量的引用。