这里的序列一致性有什么问题?

时间:2015-10-08 13:43:17

标签: c++ lock-free memory-barriers

我在C和C ++中使用无锁算法,最近偶然发现了一个我不太了解的行为。如果您有以下代码,运行它将为您提供类似

的内容
reader started
writer started
iters=79895047, less=401131, eq=48996928, more=30496988

Aren&#t; t std::atomics预计会按顺序保持一致吗?如果是这样,为什么读者有时会在b之前看到a被更新?我还试图做各种涉及内存栅栏的技巧但没有成功。完整的可编辑代码可以在https://github.com/akamaus/fence_test

看到

这个例子有什么问题?

std::atomic<uint> a(0);
std::atomic<uint> b(0);

volatile bool stop = false;

void *reader(void *p) {
    uint64_t iter_counter = 0;
    uint cnt_less = 0,
         cnt_eq = 0,
         cnt_more = 0;

    uint aa, bb;


    printf("reader started\n");

    while(!stop) {
        iter_counter++;
        aa = a.load(std::memory_order_seq_cst);
        bb = b.load(std::memory_order_seq_cst);
        if (aa < bb) {
            cnt_less++;
        } else if (aa > bb) {
            cnt_more++;
        } else {
            cnt_eq++;
        }
    }
        printf("iters=%lu, less=%u, eq=%u, more=%u\n", iter_counter, cnt_less, cnt_eq, cnt_more);

    return NULL;
}

void *writer(void *p) {
    printf("writer started\n");
    uint counter = 0;
    while(!stop) {
        a.store(counter, std::memory_order_seq_cst);
        b.store(counter, std::memory_order_seq_cst);
        counter++;
    }
}

1 个答案:

答案 0 :(得分:4)

顺序一致的内存排序意味着所有线程观察到的(使用seq cst操纵的原子对象的)修改顺序是一致的。该程序的行为就好像所有这些操作在一个总顺序中交错进行。请考虑以下情况:

Writer Reader
       a == 0
a = 1
b = 1
       b == 1

结果:aa < bb

Writer Reader
a = 1
       a == 1
       b == 0
b = 1

结果:aa > bb

带锁,例如a mutex,您可以确保操作不会交错。