std:: atomic
|
헤더에 정의됨
<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
는 복사 가능하지도 이동 가능하지도 않습니다.
|
호환성 매크로
<stdatomic.h>
가 포함될 때
|
(C++23부터) |
목차 |
특수화
기본 템플릿
기본
std::atomic
템플릿은
TriviallyCopyable
타입
T
중
CopyConstructible
와
CopyAssignable
를 모두 만족하는 어떤 타입으로도 인스턴스화될 수 있습니다. 다음 값들 중 어느 하나라도
false
인 경우 프로그램은 형식 오류를 가집니다:
- std:: is_trivially_copyable < T > :: value
- std:: is_copy_constructible < T > :: value
- std:: is_move_constructible < T > :: value
- std:: is_copy_assignable < T > :: value
- std:: is_move_assignable < T > :: value
- std:: is_same < T, typename std:: remove_cv < T > :: type > :: value
struct Counters { int a; int b; }; // 사용자 정의 trivial-copyable 타입 std::atomic<Counters> cnt; // 사용자 정의 타입에 대한 특수화
std :: atomic < bool > 는 기본 템플릿을 사용합니다. 이것은 표준 레이아웃 구조체 임이 보장되며 trivial destructor 를 가집니다.
부분 특수화
표준 라이브러리는 다음 유형들에 대해 기본 템플릿이 가지고 있지 않은 추가적인 속성을 가진
std::atomic
템플릿의 부분 특수화를 제공합니다:
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부터)
)으로 인스턴스화될 때,
또한, 결과적으로 생성된
결과가 부동 소수점 타입으로 표현 불가능한 경우에도 어떤 연산도 undefined behavior를 발생시키지 않습니다. 유효한 부동 소수점 환경 은 호출 스레드의 부동 소수점 환경과 다를 수 있습니다. |
(C++20부터) |
멤버 타입
| 유형 | 정의 | ||||
value_type
|
T
(특수화 여부와 관계없이)
|
||||
difference_type
[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 에 대해 다음과 같은 타입 별칭이 제공됩니다:
모든
|
|
|
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) |
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.
|
|
(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++11)
|
락-프리 불린 원자 타입
(클래스) |
|
(C++20)
|
원자적 공유 포인터
(클래스 템플릿 특수화) |
|
(C++20)
|
원자적 약한 포인터
(클래스 템플릿 특수화) |
|
C 문서
for
원자 타입
|
|