atomic 예제

x를 위한 코드는 두 번 감소되지만 원래 값보다 하나만 줄어듭니다. 또한 x의 테스트가 감소와 별개이기 때문에 또 다른 문제가 발생합니다: x가 두 개로 시작하고 두 스레드가 if 조건을 평가하기 전에 두 스레드가 모두 감소x인 경우 두 스레드가 action()을 호출합니다. 이 문제를 해결하려면 한 번에 하나의 스레드만 감소작업을 수행하고 “if”가 확인한 값이 감소의 결과인지 확인해야 합니다. 뮤텍스를 도입하여 이 작업을 수행할 수 있지만 x를 원자성으로 선언하고 “if(-x==0) action()”을 작성하는 것이 훨씬 빠르고 간단합니다. 원자성::연산자–는 원자성으로 작동하며 다른 스레드는 간섭할 수 없습니다. 이러한 작업은 원자적으로 발생하기 때문에 상호 배제 없이 안전하게 사용할 수 있습니다. 다음 예제를 생각해 보십시오: 예를 들어, O는 산소의 단일 원자에 대한 심볼입니다. 한편, O2는 2개의 산소 원자로 구성된 산소 가스 분자의 기호이며, O3는 3개의 산소 원자로 구성된 오존 분자의 상징이다. 나는 “5,6,7,8”가는 카운트 값이 첫 번째 예에서 완벽하게 받아 들일 수 있다고 생각합니까? 위의 프로그램을 실행하면 개수 값이 5,6,7,8 에서 다릅니다.

그 이유는 count++가 원자성 연산이 아니기 때문입니다. 따라서 한 스레드가 값을 읽고 하나씩 증분할 때 다른 스레드가 잘못된 결과로 이어지는 이전 값을 읽었습니다. 예제에 문제가 표시되지 않습니다. 스레드 주, t1 및 t2가 병렬로 실행되고 있습니다. start() 메서드가 호출되는 시기를 확인합니다. t1.join()는 주 스레드가 t1의 완료를 기다린 다음 t2.join() 주 스레드가 t2의 완료를 기다릴 때까지 기다립니다. t1과 t2가 병렬로 실행되지 않는 것과 같지 않습니다. 확실히 t1과 t2는 병렬로 실행됩니다. 이 기사에 대한 아주 좋은 Pankaj. 헤더 는 atomic_bool에서 atomic_uintmax_t에 이르는 37개의 편리한 매크로를 정의하여 기본 제공 및 라이브러리 유형으로 이 키워드의 사용을 단순화합니다.

두 함수(첫 번째 “읽기 x”와 나중에 “쓰기 x”) 사이의 간격이 다른 용도로 경합을 일으키기 때문에 개체를 “원자성”으로 만들 수 없습니다. “원자성” 개체가 필요하다고 생각되면 API 및 멤버 함수를 신중하게 디자인하여 지금 노출하여 개체에 대한 업데이트를 시작하고 커밋해야 합니다. 모든 원자 연산에 대해 보장되는 네 가지 일관성이 있습니다: std::atomic 제공의 주요 함수는 std::atomic의 내용을 원자적으로 설정하고 얻는 저장 및 로드 함수입니다.