2015-10-08 3 views
1

Я играю с блокирующими алгоритмами на C и C++ и недавно наткнулся на поведение, которое я не совсем понимаю. Если у вас есть следующий код, работает это даст вам что-то вродеЧто не так с последовательной консистенцией здесь?

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

ли не 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++; 
    } 
} 
+0

не может быть проблемой, но [volatile не следует использовать для синхронизации] (http://stackoverflow.com/questions/2484980/why-is-volatile-not-considered-useful-in-multithreaded-coror -c-programming) – NathanOliver

+2

Рассмотрите: писатель пишет 'a', затем читатель читает с' a', затем читатель читает с 'b', затем писатель пишет' b'. Результат: читатель наблюдает «a> b». Точно так же читатель читает от 'a', писатель пишет' a', писатель пишет 'b', читатель читает с' b'. Результат: читатель замечает 'a dyp

+0

Положите это другим способом - последовательная согласованность гарантирует читателям, что все записи уже выполнены. Он не ждет, когда будущие записи произойдут. Аналогичный вопрос из сегодняшнего дня [Понимание модели памяти C++: разные значения в разных прогонах] (http://stackoverflow.com/questions/33007373/understanding-c-memory-model-different-values-on-different-runs) –

ответ

4

Последовательное соответствуют упорядочению памяти означает, что порядок модификации (атомные объекты манипулируют с след сСтом), наблюдаемых всеми потоками является последовательным. Программа ведет себя так, как будто все эти операции чередуются в одном общем порядке. Рассмотрим следующие случаи:


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, вы можете убедиться, что операции не чередуются.

Смежные вопросы