2016-12-27 1 views
3

하나의 원자 변수와 std::memory_order_seq_cst을 사용하는 경우 비 원자 연산이 재정렬되지 않도록 보장됩니까? 내가 std::memory_order_seq_cst를 사용할 때memory_order_seq_cst는 비 원자 연산과 어떻게 동기화됩니까?

내가
std::atomic<bool> quux = {false}; 

void foo() { 
    bar(); 
    quux.store(true, std::memory_order_seq_cst); 
    moo(); 
} 

store의 호출 후에 순서가 묻지 않도록 보장 bar() 인 경우 예를 들어

, 및 moo()은, 한, store의 호출하기 전에 순서가 얻을하지 적어도 다른 스레드의 관점에서?

또는 코드에 넣으려면 다른 스레드에서 실행하는 경우 다음 가정이 유효합니까? 나는 가정

if(quux.load(std::memory_order_seq_cst) == true) { 
    // bar guaranteed to be called; its side-effects are visible 
    // moo might have been called, but is not guaranteed to 
} else { 
    // bar might have been called, but is not guaranteed to 
    // moo might have been called, but is not guaranteed to 
} 

참고 barmoo도 사용 작업, 뮤텍스, 잠금, 울타리 또는 다른 동기화 기능을 원자.

답변

3

하나의 원자 변수와 std::memory_order_seq_cst을 사용하는 경우 비 원자 연산이 재정렬되지 않도록 보장됩니까?

표준이 http://en.cppreference.com/w/cpp/atomic/memory_order 꽤 분명하다

memory_order_seq_cst이 메모리 순서 조작은 존재하는 획득 동작과 해제 조작 플러스, 하나의 전체 순서를 모두하는 모든 스레드 모든 수정 사항을 동일한 순서로 준수하십시오.

memory_order_acquire이 메모리 순서로로드 작업을 수행하면 해당 메모리 위치에서 획득 작업이 수행됩니다. rea ds 또는 현재 스레드의 쓰기는이로드 전에 전에 재정렬 될 수 있습니다.

memory_order_release이 메모리 저장 순서와 동작은 분리 동작을 수행 아니오 판독하거나 저장 후 재정렬 될 수 현재 스레드에 기입한다.

즉, memory_order_seq_cst 연산에 대해로드 또는 저장 (비 원자 및 원자 모두)을 다시 정렬 할 수 없습니다.


, 저장의 호출하기 전에 다시 정렬하려면 저장하지의 호출 후 다시 정렬하려면 보증되지 bar()moo() 인만큼 내가 최소한의 관점에서, 표준 : memory_order_seq_cst를 사용할 때 다른 스레드?

barmoo의 정의는 현재 번역 단위에서 사용할 수없는 경우, 컴파일러는 이러한 기능 때문에 메모리로드를 수행 및/또는 (I/O 또는 메모리에 저장을) 부작용이하고 있다고 가정 memory_order_seq_cst 작업을 재정렬 할 수 없습니다.

정의가 사용 가능하고 함수가 I/O 또는 메모리로드/저장을 수행하지 않으면 다시 정의 할 수 있습니다.이것들은 pure functions이거나 아무것도하지 않고 void 또는 상수를 반환하는 함수입니다.

+0

Nitpicking, 그러나 : cppreference.com은 훌륭하지만 ISO 표준은 아닙니다. – Zeta

+0

@Zeta 맞습니다. 나는 그것이 표준의 사본이 아니기 때문에 cppreference.com이 아주 정확하다는 것을 알았지 만 생략이있을 수있다. –

-2

가장 엄격한 메모리 순서가 사용되기 때문에 function bar와 moo는 각각 quux 할 저장소 이전 또는 이전에 재정렬 될 수 없습니다.

if-else의 경우에 대한 결론이 정확하지 않습니다.

표현식 if(quux.load(std::memory_order_seq_cst) == true)이 참으로 평가되면 함수 표시 줄이 이미 호출을 완료 할 것입니다. 음매에 대한 호출 순서를 결정할 수 없습니다. 완료되지 않았거나 시작되지 않았거나 통화 중일 수 있습니다.

위의 표현식이 false로 평가되면 두 함수의 순서를 결정할 수 없습니다. 표현식이 거짓으로 평가되는 순간에 moo라는 함수는 아직 호출되지 않았지만 실행 직전에 else 절로 진행되기 전에 호출 될 수 있습니다. else 절에서 함수 moo의 상태는 이전 단락과 동일합니다 (확인할 수 없음).

0

@ Maxim에 의해 링크 된 http://en.cppreference.com/w/cpp/atomic/memory_order 링크에 따르면 memory_order_seq_cst와 관련하여 오류가 있습니다. 위의 텍스트는 memory_order_acq_rel과 교환됩니다. memory_order_seq_cst의 텍스트 :

memory_order_seq_cst :이 메모리 순서로로드 조작은 획득 조작을 수행하고 상점은 해제 조작을 수행하며 read-modify-write는 획득 조작과 해제 조작과 단일 전체 합계를 수행합니다 모든 스레드가 동일한 순서로 모든 수정을 관찰하는 순서가 있습니다. (아래의 순차적 일관성있는 순서 참조)

따라서 저장소 작업은 moo()가 울타리보다 먼저 재정렬 될 수 있음을 의미하는 릴리스와 같습니다.

관련 문제