2013-10-30 1 views
2

C++ 11에서 두 개의 스레드간에 비 원자 데이터를 전송하는 데 std :: atomic을 사용할 수 있습니까? 자세히 말하면, 다음의 4 가지 의미가 모두 원자 적으로 설정되어 있는가?C++ 11에서 두 개의 스레드 사이에 비 원자 데이터를 전송하는 데 std :: atomic을 사용할 수 있습니까?

  1. (그 C++ 문에 의해 생성 된 모든 기계 명령어를 포함하여 실행에 대해 이야기 할 때) 원자 쓰기 문 전은 원자 쓰기 전에 실행되는 모든 문.

  2. 원자 읽기 후에 원자 읽기가 실행 된 후 모든 명령문 (해당 C++ 명령문에 의해 생성 된 모든 기계 명령어를 포함하여 실행에 대해 이야기 할 때).

  3. 원자를 쓰기 전에 다른 모든 메모리 쓰기는 주 메모리에 위탁됩니다.

  4. 원자를 읽은 후 다른 모든 메모리 읽기는 주 메모리에서 다시 읽습니다 (이는 쓰레드 캐시를 버리는 것을 의미합니다).

여기 예를 보았다 : http://bartoszmilewski.com/2008/12/01/c-atomics-and-memory-ordering/

그러나 예에서, 데이터는 그래서 제 질문은 어떤 데이터가있는 경우 비 원자이며, 원자입니까? 여기

내가 원하는 것을 보여주는 몇 가지 코드 :

공통 데이터 :

std::atomic_bool ready; 
char* data; // or data of any other non atomic 

쓰기 스레드 :

data = new char[100]; 
data[0] = 1; 
ready.store(true); // use default memory_order(memory_order_seq_cst), witch i think is the most restrict one 

읽기 스레드 : 내가 생각

if(ready.load()) { // use default memory_order(memory_order_seq_cst) 
    assert(data[0] == 1); // both data(of type char*) and data[0~99](each of type char) are loaded 
} 

답변

1

메모리 주문을 사용해야합니다 :

data = new char[100]; 
data[0] = 1; 
ready.store_explicit(true, std::memory_order_release); 

if(ready.load_explicit(std::memory_order_aqcuire)) { 
    assert(data[0] == 1); // both data(of type char*) and data[0~99](each of type char) are loaded 
} 

이 실제로 코드가 정확하지만,이 경우이 초/중부 표준시 메모리 순서 필요가없고 acquire/release가 올바른지 (내가이 구문 _explicit에 대해 확실하지 않다). 과 release 원자 쓰기 후에는 쓰기가 다시 정렬 될 수없고 acquire로드가없는 원자로드가 원자 순서로 재 배열 될 수 있으므로 원자 저장소 이전의 모든 비 원자 저장소가 원자로드 후에 모든로드에서 표시 될 수 있습니다.

+8

기본 메모리 순서는'acquire/release'보다 훨씬 더 제한적인'memory_order_seq_cst'입니다. – inf

+0

@bamboon 오, 네 말이 맞아,하지만 어느 쪽이든 맞는 것 같아? – MRB

+0

예, 모든 쓰기가 다른 스레드에서 볼 수있게되므로 acq/rel이 충분해야합니다. – inf

관련 문제