2014-01-22 44 views
4

在這個例子中:採集/釋放內存訂貨

#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 - 如果我用的std :: memory_order_acquire替換的std :: memory_order_acq_rel在thread_2,我仍然可以保證在thread_3斷言絕不會火?

2 - 可以std :: memory_order_release使用std :: memory_order_acquire與2個線程同步(如果2個線程正在通過獲取語義觀察相同的標誌)?

+0

僅供參考,'ATOMIC_VAR_INIT(foo)'提供C兼容性,'std :: atomic flag {foo};'具有完全相同的效果。 – Casey

回答

0
  1. 在線程2中沒有什麼可以同步的,所以std :: memory_order_relaxed內存排序在這裏更加合理。

  2. 在std :: memory_order_release標記變量x的存儲同步-用的std :: memory_order_acquire標記變量x甚至初始存儲的負載是接着用原子讀 - 修改 - 寫操作的序列上x