여러 스레드가 공유 전역 변수에 동시에 액세스하는 경우 스레드는 다음을 사용하여 변수에 쓰고 읽을 수 있습니다. 서로 다른 프로세서 코어에 캐시된 서로 다른 복사본. 서로 다른 캐시에 저장된 값 사이의 잠재적 불일치로 인해 하나의 스레드가 캐시에서 오래된 값을 읽을 수 있습니다.
그러나 C 11 표준은 원자성 작업을 위한 std::atomic 라이브러리를 제공합니다. , 다른 캐시에서 최신 값을 읽도록 합니다. 이는 한 스레드에서 변경한 사항이 일관된 순서로 다른 스레드에 표시되도록 보장하는 강력한 메모리 순서 지정을 통해 달성됩니다.
반면에 휘발성 키워드는 단순히 변수를 다음과 같이 최적화해서는 안 된다는 것을 나타냅니다. 컴파일러는 원자적 액세스를 보장하지 않습니다. 이는 주로 메모리 매핑된 I/O 또는 신호 처리와 같은 시나리오를 위해 설계되었습니다.
다음과 같은 스레드 간 공유 변수의 맥락에서:
std::atomic<int> ai;
의 동작 휘발성 및 원자 유형은 크게 다릅니다. 휘발성은 원자 액세스를 보장하지 않으며 std::atomic과 함께 사용하는 것은 중복됩니다. 하드웨어 플랫폼이 달리 지정하는 경우 휘발성은 스레드 간 원자 액세스 또는 메모리 순서와 관련이 없을 수 있습니다.
반면에 std::atomic 유형은 std::memory_order_seq_cst와 같은 다양한 옵션을 통해 메모리 순서를 제공합니다. , 모든 변수에 걸쳐 모든 원자 작업에 대해 단일 전체 순서를 적용합니다. 이렇게 하면 가시성과 순서 제약 조건이 유지되고 스레드가 엄격하게 정의된 순서에 따라 오래된 값을 관찰하지 않게 됩니다.
또한 exchange(), Compare_exchange_strong() 및 fetch_add와 같은 읽기-수정-쓰기 작업을 사용합니다. ()는 최신 값에 대한 액세스를 보장합니다. 동일한 스레드 컨텍스트 내에서 이러한 작업을 실행함으로써 스레드는 업데이트된 값을 올바른 순서로 관찰하여 불일치를 방지합니다.
원자적 작업을 수행하려면 신중한 고려와 이해가 필요합니다. 프로덕션 코드에서 원자적 연산을 효과적으로 구현하려면 배경 자료와 기존 코드를 철저히 조사하는 것이 좋습니다. 대부분의 경우 잠금은 원자적 작업이 필요하지 않을 때 실행 가능한 대안을 제공할 수 있습니다.
위 내용은 동시 C 11 프로그래밍에서 `std::atomic`과 `휘발성`은 어떻게 다른가요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!