2014-01-22 3 views
4

В примере:Приобретать/Release Память заказа

#include <thread> 
#include <atomic> 
#include <cassert> 
#include <vector> 

std::vector<int> data; 
std::atomic<int> flag = ATOMIC_VAR_INIT(0); 

void thread_1() 
{ 
    data.push_back(42); 
    flag.store(1, std::memory_order_release); 
} 

void thread_2() 
{ 
    int expected=1; 
    while (!flag.compare_exchange_strong(expected, 2, std::memory_order_acq_rel)) { 
     expected = 1; 
    } 
} 

void thread_3() 
{ 
    while (flag.load(std::memory_order_acquire) < 2) 
     ; 
    assert(data.at(0) == 42); // will never fire 
} 

int main() 
{ 
    std::thread a(thread_1); 
    std::thread b(thread_2); 
    std::thread c(thread_3); 
    a.join(); b.join(); c.join(); 
} 

1- Если я заменяю зЬй :: memory_order_acq_rel в thread_2 по станд :: memory_order_acquire, могу ли я гарантировать, что утверждение в thread_3 никогда не будет стрелять?

2 - Может ли std :: memory_order_release синхронизировать с 2 потоками, используя std :: memory_order_acquire (если 2 потока просматривают один флаг с семантикой получения)?

+0

FYI, 'ATOMIC_VAR_INIT (foo)' предоставляется для совместимости с C, 'std :: atomic flag {foo};' имеет точно такой же эффект. – Casey

ответ

0
  1. Вы не имеют никакого отношения к synchonize-с в потоке 2, так станд :: memory_order_relaxed упорядочение памяти является более рациональным здесь.

  2. ЗППП :: memory_order_release помечено магазин переменной x синхронизирует-с стандом :: memory_order_acquire помечено нагрузками переменного x даже начального магазина следует последовательность атомарных операций чтения-записи изменить на x

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