Namespaces
Variants

std:: atomic

From cppreference.net
Concurrency support library
Threads
(C++11)
(C++20)
this_thread namespace
(C++11)
(C++11)
Cooperative cancellation
Mutual exclusion
Generic lock management
Condition variables
(C++11)
Semaphores
Latches and Barriers
(C++20)
(C++20)
Futures
(C++11)
(C++11)
(C++11)
Safe reclamation
Hazard pointers
Atomic types
atomic
(C++11)
(C++20)
Initialization of atomic types
(C++11) (deprecated in C++20)
(C++11) (deprecated in C++20)
Memory ordering
(C++11) (deprecated in C++26)
Free functions for atomic operations
Free functions for atomic flags
헤더에 정의됨 <atomic>
template < class T >
struct atomic ;
(1) (C++11부터)
template < class U >
struct atomic < U * > ;
(2) (C++11부터)
헤더에 정의됨 <memory>
template < class U >
struct atomic < std:: shared_ptr < U >> ;
(3) (C++20부터)
template < class U >
struct atomic < std:: weak_ptr < U >> ;
(4) (C++20부터)
헤더에 정의됨 <stdatomic.h>
#define _Atomic(T) /* see below */
(5) (C++23부터)

std::atomic 템플릿의 각 인스턴스화와 완전 특수화는 원자적 타입을 정의합니다. 한 스레드가 원자적 객체에 쓰는 동시에 다른 스레드가 이를 읽는 경우, 그 동작은 잘 정의됩니다(데이터 경쟁에 대한 상세 내용은 메모리 모델 을 참조하십시오).

또한, 원자적 객체에 대한 접근은 스레드 간 동기화를 설정하고 std::memory_order 에 지정된 대로 비원자적 메모리 접근의 순서를 정할 수 있습니다.

std::atomic 는 복사 가능하지도 이동 가능하지도 않습니다.

호환성 매크로 _Atomic <stdatomic.h> 에 제공되며, _Atomic(T) std::atomic<T> 와 동일합니다 (둘 다 올바른 형식일 경우).

<stdatomic.h> 가 포함될 때 std 네임스페이스에 선언이 사용 가능한지 여부는 명시되지 않습니다.

(C++23부터)

목차

특수화

기본 템플릿

기본 std::atomic 템플릿은 TriviallyCopyable 타입 T CopyConstructible CopyAssignable 를 모두 만족하는 어떤 타입으로도 인스턴스화될 수 있습니다. 다음 값들 중 어느 하나라도 false 인 경우 프로그램은 형식 오류를 가집니다:

struct Counters { int a; int b; }; // 사용자 정의 trivial-copyable 타입
std::atomic<Counters> cnt;         // 사용자 정의 타입에 대한 특수화

std :: atomic < bool > 는 기본 템플릿을 사용합니다. 이것은 표준 레이아웃 구조체 임이 보장되며 trivial destructor 를 가집니다.

부분 특수화

표준 라이브러리는 다음 유형들에 대해 기본 템플릿이 가지고 있지 않은 추가적인 속성을 가진 std::atomic 템플릿의 부분 특수화를 제공합니다:

2) 모든 포인터 타입에 대한 부분 특수화 std::atomic<U*> . 이 특수화들은 표준 레이아웃을 가지며 , trivial 기본 생성자, (C++20까지) 그리고 trivial 소멸자를 가집니다. 모든 atomic 타입에 제공되는 연산 외에, 이 특수화들은 추가적으로 포인터 타입에 적합한 atomic 산술 연산들을 지원합니다, 예를 들어 fetch_add , fetch_sub .
3,4) 부분 특수화 std :: atomic < std:: shared_ptr < U >> std :: atomic < std:: weak_ptr < U >> std::shared_ptr std::weak_ptr 에 대해 제공됩니다.

자세한 내용은 std::atomic <std::shared_ptr> std::atomic <std::weak_ptr> 를 참조하십시오.

(C++20부터)

정수형에 대한 특수화

다음 정수형 타입 중 하나로 인스턴스화될 때, std::atomic fetch_add , fetch_sub , fetch_and , fetch_or , fetch_xor 와 같은 정수형 타입에 적합한 추가적인 원자 연산들을 제공합니다:

  • 문자 타입 char , char8_t (C++20부터) , char16_t , char32_t , 그리고 wchar_t ;
  • 표준 부호 있는 정수 타입: signed char , short , int , long , 그리고 long long ;
  • 표준 부호 없는 정수 타입: unsigned char , unsigned short , unsigned int , unsigned long , 그리고 unsigned long long ;
  • <cstdint> 헤더의 typedef에 필요한 추가 정수 타입들.

추가적으로, 결과적인 std::atomic< Integral > 특수화는 표준 레이아웃을 가지며 , trivial 기본 생성자, (C++20 이전) 그리고 trivial 소멸자를 가집니다. 부호 있는 정수 연산은 2의 보수를 사용하도록 정의되어 있으며, 정의되지 않은 결과는 존재하지 않습니다.

부동 소수점 타입에 대한 특수화

cv-unqualified 부동 소수점 타입( float , double , long double 그리고 cv-unqualified 확장 부동 소수점 타입 (C++23부터) )으로 인스턴스화될 때, std::atomic fetch_add fetch_sub 과 같은 부동 소수점 타입에 적합한 추가적인 원자적 연산을 제공합니다.

또한, 결과적으로 생성된 std::atomic< Floating > 특수화는 표준 레이아웃을 가지며 trivial destructor를 가집니다.

결과가 부동 소수점 타입으로 표현 불가능한 경우에도 어떤 연산도 undefined behavior를 발생시키지 않습니다. 유효한 부동 소수점 환경 은 호출 스레드의 부동 소수점 환경과 다를 수 있습니다.

(C++20부터)

멤버 타입

유형 정의
value_type T (특수화 여부와 관계없이)
difference_type [1]

value_type ( atomic< Integral > atomic< Floating > (C++20부터) 특수화에만 해당)

std::ptrdiff_t ( std::atomic<U*> 특수화에만 해당)

  1. difference_type 는 기본 std::atomic 템플릿이나 std::shared_ptr std::weak_ptr 에 대한 부분 특수화에서 정의되지 않습니다.

멤버 함수

원자적 객체를 생성함
(public member function)
원자적 객체에 값을 저장함
(public member function)
원자적 객체가 lock-free인지 확인함
(public member function)
원자적으로 원자적 객체의 값을 비원자적 인수로 대체함
(public member function)
원자적 객체의 값을 원자적으로 획득함
(public member function)
원자적 객체에서 값을 로드함
(public member function)
원자적 객체의 값을 원자적으로 대체하고 이전에 보유한 값을 획득함
(public member function)
원자적 객체의 값을 비원자적 인수와 원자적으로 비교하고, 같으면 원자적 교환을 수행하거나 같지 않으면 원자적 로드를 수행함
(public member function)
(C++20)
알림을 받고 원자적 값이 변경될 때까지 스레드를 차단함
(public member function)
(C++20)
원자적 객체를 기다리는 스레드 중 적어도 하나에게 알림을 보냄
(public member function)
(C++20)
원자적 객체를 기다리며 차단된 모든 스레드에게 알림을 보냄
(public member function)

상수

[static] (C++17)
해당 타입이 항상 lock-free임을 나타냄
(public static member constant)

특수화된 멤버 함수

정수형 , 부동소수점형 (C++20부터) 및 포인터 타입 전용
원자적으로 인자를 원자 객체에 저장된 값에 더하고 이전에 보유했던 값을 얻음
(public member function)
원자적으로 원자 객체에 저장된 값에서 인자를 빼고 이전에 보유했던 값을 얻음
(public member function)
원자 값에 더하거나 뺌
(public member function)
정수형 및 포인터 타입 전용
(C++26)
원자적으로 인자와 원자 객체의 값 사이에 std::max 를 수행하고 이전에 보유했던 값을 얻음
(public member function)
(C++26)
원자적으로 인자와 원자 객체의 값 사이에 std::min 를 수행하고 이전에 보유했던 값을 얻음
(public member function)
원자 값을 1씩 증가 또는 감소
(public member function)
정수형 전용
원자적으로 인자와 원자 객체의 값 사이에 비트 AND를 수행하고 이전에 보유했던 값을 얻음
(public member function)
원자적으로 인자와 원자 객체의 값 사이에 비트 OR를 수행하고 이전에 보유했던 값을 얻음
(public member function)
원자적으로 인자와 원자 객체의 값 사이에 비트 XOR를 수행하고 이전에 보유했던 값을 얻음
(public member function)
원자 값과 비트 AND, OR, XOR를 수행
(public member function)

타입 별칭

위에 나열된 모든 정수형과 bool 에 대해 다음과 같은 타입 별칭이 제공됩니다:

모든 std::atomic<Integral> 에 대한 별칭
atomic_bool
(C++11)
std :: atomic < bool >
(typedef)
atomic_char
(C++11)
std :: atomic < char >
(typedef)
atomic_schar
(C++11)
std :: atomic < signed char >
(typedef)
atomic_uchar
(C++11)
std :: atomic < unsigned char >
(typedef)
atomic_short
(C++11)
std :: atomic < short >
(typedef)
atomic_ushort
(C++11)
std :: atomic < unsigned short >
(typedef)
atomic_int
(C++11)
std :: atomic < int >
(typedef)
atomic_uint
(C++11)
std :: atomic < unsigned int >
(typedef)
atomic_long
(C++11)
std :: atomic < long >
(typedef)
atomic_ulong
(C++11)
std :: atomic < unsigned long >
(typedef)
atomic_llong
(C++11)
std :: atomic < long long >
(typedef)
atomic_ullong
(C++11)
std :: atomic < unsigned long long >
(typedef)
atomic_char8_t
(C++20)
std :: atomic < char8_t >
(typedef)
atomic_char16_t
(C++11)
std :: atomic < char16_t >
(typedef)
atomic_char32_t
(C++11)
std :: atomic < char32_t >
(typedef)
atomic_wchar_t
(C++11)
std :: atomic < wchar_t >
(typedef)
atomic_int8_t
(C++11) (선택적)
std :: atomic < std:: int8_t >
(typedef)
atomic_uint8_t
(C++11) (선택적)
std :: atomic < std:: uint8_t >
(typedef)
atomic_int16_t
(C++11) (선택적)
std :: atomic < std:: int16_t >
(typedef)
atomic_uint16_t
(C++11) (선택적)
std :: atomic < std:: uint16_t >
(typedef)
atomic_int32_t
(C++11) (선택적)
std :: atomic < std:: int32_t >
(typedef)
atomic_uint32_t
(C++11) (선택적)
std :: atomic < std:: uint32_t >
(typedef)
atomic_int64_t
(C++11) (선택적)
std :: atomic < std:: int64_t >
(typedef)
atomic_uint64_t
(C++11) (선택적)
std :: atomic < std:: uint64_t >
(typedef)
atomic_int_least8_t
(C++11)
std :: atomic < std:: int_least8_t >
(typedef)
atomic_uint_least8_t
(C++11)
std :: atomic < std:: uint_least8_t >
(typedef)
atomic_int_least16_t
(C++11)
std :: atomic < std:: int_least16_t >
(typedef)
atomic_uint_least16_t
(C++11)
std :: atomic < std:: uint_least16_t >
(typedef)
atomic_int_least32_t
(C++11)
std :: atomic < std:: int_least32_t >
(typedef)
atomic_uint_least32_t
(C++11)
std :: atomic < std:: uint_least32_t >
(typedef)
atomic_int_least64_t
(C++11)
std :: atomic < std:: int_least64_t >
(typedef)
atomic_uint_least64_t
(C++11)
std :: atomic < std:: uint_least64_t >
(typedef)
atomic_int_fast8_t
(C++11)
std :: atomic < std:: int_fast8_t >
(typedef)
atomic_uint_fast8_t
(C++11)
std :: atomic < std:: uint_fast8_t >
(typedef)
atomic_int_fast16_t
(C++11)
std :: atomic < std:: int_fast16_t >
(typedef)
atomic_uint_fast16_t
(C++11)
std :: atomic < std:: uint_fast16_t >
(typedef)
atomic_int_fast32_t
(C++11)
std :: atomic < std:: int_fast32_t >
(typedef)
atomic_uint_fast32_t
(C++11)
std :: atomic < std:: uint_fast32_t >
(typedef)
atomic_int_fast64_t
(C++11)
std :: atomic < std:: int_fast64_t >
(typedef)
atomic_uint_fast64_t
(C++11)
std :: atomic < std:: uint_fast64_t >
(typedef)
atomic_intptr_t
(C++11) (선택적)
std :: atomic < std:: intptr_t >
(typedef)
atomic_uintptr_t
(C++11) (선택적)
std :: atomic < std:: uintptr_t >
(typedef)
atomic_size_t
(C++11)
std :: atomic < std:: size_t >
(typedef)
atomic_ptrdiff_t
(C++11)
std :: atomic < std:: ptrdiff_t >
(typedef)
atomic_intmax_t
(C++11)
std :: atomic < std:: intmax_t >
(typedef)
atomic_uintmax_t
(C++11)
std :: atomic < std:: uintmax_t >
(typedef)
특수 목적 타입에 대한 별칭
atomic_signed_lock_free
(C++20)
락 프리이며 대기/알림이 가장 효율적인 부호 있는 정수형 atomic 타입
(typedef)
atomic_unsigned_lock_free
(C++20)
락 프리이며 대기/알림이 가장 효율적인 부호 없는 정수형 원자 타입
(typedef)
Note: std::atomic_int N _t , std::atomic_uint N _t , std::atomic_intptr_t , and std::atomic_uintptr_t are defined if and only if std::int N _t , std::uint N _t , std::intptr_t , and std::uintptr_t are defined, respectively.

std::atomic_signed_lock_free std::atomic_unsigned_lock_free 는 독립형 구현에서 선택적(optional)입니다.

(C++20부터)

참고 사항

std::atomic 의 모든 멤버 함수에 대해 비멤버 함수 템플릿 equivalents가 존재합니다. 이러한 비멤버 함수들은 std::atomic 의 특수화가 아니지만 원자성을 보장할 수 있는 타입에 대해 추가적으로 오버로드될 수 있습니다. 표준 라이브러리에서 이러한 유일한 타입은 std:: shared_ptr < U > 입니다.

_Atomic 는 C에서 키워드 로서 atomic 타입 을 제공하기 위해 사용됩니다.

구현체는 모든 가능한 타입 T 에 대해 C 언어의 _Atomic(T) 표현이 C++의 std::atomic<T> 표현과 동일하도록 보장하는 것이 권장됩니다. 원자성과 메모리 순서를 보장하기 위해 사용되는 메커니즘은 상호 호환되어야 합니다.

GCC와 Clang에서 여기서 설명하는 기능 중 일부는 -latomic 에 대한 링크가 필요합니다.

기능 테스트 매크로 표준 기능
__cpp_lib_atomic_ref 201806L (C++20) std::atomic_ref
__cpp_lib_constexpr_atomic 202411L (C++26) constexpr std::atomic std::atomic_ref

예제

#include <atomic>
#include <iostream>
#include <thread>
#include <vector>
std::atomic_int acnt;
int cnt;
void f()
{
    for (auto n{10000}; n; --n)
    {
        ++acnt;
        ++cnt;
        // 참고: 이 예제에서는 완화된 메모리 순서로 충분합니다,
        // 예: acnt.fetch_add(1, std::memory_order_relaxed);
    }
}
int main()
{
    {
        std::vector<std::jthread> pool;
        for (int n = 0; n < 10; ++n)
            pool.emplace_back(f);
    }
    std::cout << "원자 카운터는 " << acnt << '\n'
              << "비원자 카운터는 " << cnt << '\n';
}

가능한 출력:

The atomic counter is 100000
The non-atomic counter is 69696

결함 보고서

다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.

DR 적용 대상 게시된 동작 올바른 동작
LWG 2441 C++11 고정 너비 정수 타입에 대한 atomic optional 버전의
typedef 가 누락됨
추가됨
LWG 3012 C++11 std::atomic<T> 가 trivially copyable하지만 copyable하지 않은
T 에 대해 허용됨
해당 특수화가 금지됨
LWG 3949 C++17 C++17에서 std :: atomic < bool > 이 trivial 소멸자를
가져야 한다는 문구가 실수로 삭제됨
다시 추가됨
LWG 4069
( P3323R1 )
C++11 cv-qualified T 에 대한 지원이 불명확했음 T 가 cv-qualified되는 것을 금지
P0558R1 C++11 atomic 타입에 대한 일부 함수의 템플릿 인자 추론이
실패할 수 있었음; 유효하지 않은 포인터 연산이 제공됨
명세가 크게 재작성됨:
멤버 typedef value_type
difference_type 이 추가됨

참고 항목

락-프리 불린 원자 타입
(클래스)
원자적 공유 포인터
(클래스 템플릿 특수화)
원자적 약한 포인터
(클래스 템플릿 특수화)
C 문서 for 원자 타입