2016-06-04 1 views
0

Предположим, у меня есть следующий фрагмент кода:Атомные значения изменения в расслабленном порядке

std::atomic<int> a(0); 

void thread1() 
{ 
    int x = a.fetch_add(1, std::memory_order_relaxed); 
    std::cout << x << std::endl; 
} 

void thread2() 
{ 
    int x = a.fetch_add(1, std::memory_order_relaxed); 
    std::cout << x << std::endl; 
} 

int main() 
{ 
    std::thread t1(thread1); 
    std::thread t2(thread2); 

    t1.join(); 
    t2.join(); 
} 

Вопрос: можно ли получить 0 0 в результате?

Здесь оба потока читают и изменяют a в порядке расслабленной памяти, поэтому кажется, что оба они могут видеть нулевое значение a. Но на практике я вижу только 0 1 или 1 0.

+0

Расслабленный заказ о (отсутствии) синхронизации. У вашего кода нет проблемы с синхронизацией. Операции Atomic RMW по-прежнему должны быть правильными, даже если они не упорядочены. –

ответ

2

Нет, 0 0 невозможно. Расслабленный порядок памяти не означает, что операции не являются атомарными, и единственный способ для 0 0 произойти - это чтение-модификация-запись как неатомная. Но так как std::atomic::fetch_add работает атомарно, мы знаем, что только один fetch_add может работать одновременно, поэтому возможны только 0 1 или 1 0.