std::atomic<int> x(0);
가이 전 기능하고 있다고 가정하자 다음 사항을 고려하십시오 :
memory_order_relaxed 편안 작동 : description for acquire release memory ordering을 바탕으로
int x_old = x.fetch_add(1,std::memory_order_acq_rel);
: 동기화 또는 순서 제약이 없으며 원 자성 만 있습니다. 더 판독하거나 현재 스레드의 값은 현재로드 캔에 따라 기록이 동작에 필요한
memory_order_consume (아래 편안한 순서 참조)이 기억 순서와로드 동작은 영향을받은 메모리 위치에 조작을 소비하지 수행 이로드 전에 재정렬해야합니다. 동일한 원자 변수를 해제하는 다른 스레드의 데이터 종속 변수에 대한 쓰기는 현재 스레드에서 볼 수 있습니다. 대부분의 플랫폼에서이 컴파일러 최적화에만 영향이 메모리 주문
memory_order_acquire로드 조작 (아래 주문 릴리스-소비 참조) 영향을받는 메모리 위치에서 획득 작업을 수행 : 더 읽거나 현재의 thread로 기록 할 수 이로드 전에 재정렬해야합니다. 더 읽거나에 쓴다 동일한 원자 변수를 공개 다른 스레드에서 모든 기록은 현재 스레드에 표시되어이 메모리 위해 함께 저장 조작이 해제 동작 수행
memory_order_release을 (릴리스-획득 아래 주문 없음 참조) 현재 스레드는이 저장소 이후에 재정렬 될 수 있습니다. 현재 스레드의 모든 쓰기는 동일한 원자 변수 (아래의 Release-Acquire 순서 참조)를 가져 오는 다른 스레드에서 볼 수 있으며 원자 변수에 대한 종속성을 갖는 쓰기는 동일한 원자를 사용하는 다른 스레드에서 볼 수있게됩니다 (릴리스 소비 아래에서 주문).
memory_order_acq_rel이 메모리 순서로 읽기 - 수정 - 쓰기 작업은 획득 작업과 릴리스 작업입니다. 이 스레드 이전 또는 이후에 현재 스레드의 메모리 읽기 또는 쓰기를 다시 정렬 할 수 없습니다. 동일한 원자 변수를 해제하는 다른 스레드의 모든 쓰기는 수정 전에 표시되며 수정은 동일한 원자 변수를 획득하는 다른 스레드에서 볼 수 있습니다. memory_order_seq_cst
(아래 순차적 일관된 순서 참조) 획득 동작과 해제 동작을 플러스하는 모든 스레드가 동일한 순서로 모든 변형을 관찰 존재하는 하나의 전체 순서가 모두되어이 기억 순서와 상관 연산
두 개의 별개 스레드가 동일한 x_old
값을 0으로받을 수 있습니까? 아니면 x_old
이 0 중 하나에 대해서만 0으로 실행되도록 보장되며 다른쪽에 대해서는 1입니다.
x_old
이 모두 0 일 수있는 경우 메모리 순서를 std::memory_order_seq_cst
으로 변경하면 x_old
의 고유성이 보장됩니까?
메모리 순서는 관련이 없습니다. 두 개의 스레드는 동일한 값을 가질 수 없습니다 (각 스레드에서 한 번만 표현식에 도달했다고 가정). – 2501
메모리 순서가 중요하지 않은 이유는 무엇입니까? 읽기 - 수정 - 쓰기 연산에 대해 보장 된 읽기 - 읽기 순서가 없기 때문에 두 스레드가 모두 acq_rel에서 동일한 x_old를 가질 수 없었습니까? –
주문은 여기서 간단하게 관련이 없습니다. fetch_add에서 반환되는 처음 두 값은 항상 0과 1이지만 어떤 스레드가 어떤 값을 가져올 지 보장하지 않습니다. 선택한 memory_order에 관계없이 적용됩니다. – 2501