1

我一直在阅读并尝试原子内存访问以进行同步,主要用于教育目的。具体来说,我正在研究 Mac OS X 的OSAtomic*功能系列。这是我不明白的:为什么没有办法以原子方式设置变量而不是修改它(添加、递增等)?OSAtomicCompareAndSwap*尽可能接近——但只有交换是原子的,而不是整个函数本身。这会导致以下代码不起作用:

const int N = 100000; 

void* threadFunc(void *data) {
    int *num = (int *)data;

    // Wait for main thread to start us so all spawned threads start
    // at the same time.   
    while (0 == num) { }

    for (int i = 0; i < N; ++i) {
        OSAtomicCompareAndSwapInt(*num, *num+1, num);
    }
}

// called from main thread
void test() {
    int num = 0;

    pthread_t threads[5];

    for (int i = 0; i < 5; ++i) {
        pthread_create(&threads[i], NULL, threadFunc, &num);
    }

    num = 1;

    for (int i = 0; i < 5; ++i) {
        pthread_join(threads[i], NULL);
    }

    printf("final value: %d\n", num);

}

运行时,此示例理想情况下会产生 500,001 作为最终值。但是,它没有;即使线程 X 中 OSAtomicCompareAndSwapInt 中的比较成功,另一个线程 Y 也可以在 X 有机会更改变量之前先进入设置变量。

我知道在这个简单的示例中,我可以(并且应该!)简单地使用OSAtomicAdd32,在这种情况下代码可以工作。但是,例如,如果我想以原子方式设置一个指针,使其指向另一个线程可以使用的新对象,该怎么办?

我查看了其他 API,它们似乎也缺少此功能,这使我相信这是有充分理由的,而我的困惑只是基于缺乏知识。如果有人可以启发我,我将不胜感激。

4

1 回答 1

2

我认为您必须检查OSAtomicCompareAndSwapInt结果以保证int实际设置了。

于 2013-06-27T00:22:35.340 回答