표준 라이브러리 헤더 <stdatomic.h>
표준 라이브러리 헤더 <stdatomic.h> (C11)
여러 스레드가 같은 변수를 동시에 건드리면 데이터 경쟁이 생겨요. _Atomic 타입은 이 문제를 언어 수준에서 풀지만, 매번 _Atomic이라고 쓰기보다 편리한 이름으로 쓰고 싶을 때가 많죠. <stdatomic.h>는 동시성 지원 라이브러리의 일부로, 원자 연산에 필요한 타입 별칭·함수·매크로를 제공해요. 원자 타입 선언 자체의 의미는 언어 수준의 원자 타입 문서와 함께 보면 좋아요.
출처: cppreference
본문
원자 연산(Atomic operations)
원자 타입에 대한 연산(Operations on atomic types)
| 이름 | 설명 |
|---|---|
ATOMIC_BOOL_LOCK_FREE, ATOMIC_CHAR_LOCK_FREE, ATOMIC_CHAR8_T_LOCK_FREE, ATOMIC_CHAR16_T_LOCK_FREE, ATOMIC_CHAR32_T_LOCK_FREE, ATOMIC_WCHAR_T_LOCK_FREE, ATOMIC_SHORT_LOCK_FREE, ATOMIC_INT_LOCK_FREE, ATOMIC_LONG_LOCK_FREE, ATOMIC_LLONG_LOCK_FREE, ATOMIC_POINTER_LOCK_FREE |
(C11) 주어진 원자 타입이 락프리(lock-free)인지 나타내는 매크로 상수 |
atomic_is_lock_free |
(C11) 원자 객체가 락프리인지 나타냄 |
atomic_store / atomic_store_explicit |
(C11) 원자 객체에 값을 저장 |
atomic_load / atomic_load_explicit |
(C11) 원자 객체에서 값을 읽음 |
atomic_exchange / atomic_exchange_explicit |
(C11) 원자 객체의 값과 교환 |
atomic_compare_exchange_strong, atomic_compare_exchange_strong_explicit, atomic_compare_exchange_weak, atomic_compare_exchange_weak_explicit |
(C11) 기대하는 값과 같으면 값을 교환하고, 다르면 기존 값을 읽음 |
atomic_fetch_add / atomic_fetch_add_explicit |
(C11) 원자 덧셈 |
atomic_fetch_sub / atomic_fetch_sub_explicit |
(C11) 원자 뺄셈 |
atomic_fetch_or / atomic_fetch_or_explicit |
(C11) 원자 비트 OR |
atomic_fetch_xor / atomic_fetch_xor_explicit |
(C11) 원자 비트 배타적 OR |
atomic_fetch_and / atomic_fetch_and_explicit |
(C11) 원자 비트 AND |
플래그 타입과 연산(Flag type and operations)
| 이름 | 설명 |
|---|---|
atomic_flag |
(C11) 락프리 원자 불리언 플래그 구조체 |
atomic_flag_test_and_set / atomic_flag_test_and_set_explicit |
(C11) atomic_flag를 true로 설정하고 기존 값을 반환 |
atomic_flag_clear / atomic_flag_clear_explicit |
(C11) atomic_flag를 false로 설정 |
초기화(Initialization)
| 이름 | 설명 |
|---|---|
atomic_init |
(C11) 이미 존재하는 원자 객체를 초기화 |
ATOMIC_VAR_INIT |
(C11)(C17에서 폐기, C23에서 제거) 새 원자 객체를 초기화하는 함수 매크로 |
ATOMIC_FLAG_INIT |
(C11) 새 atomic_flag를 초기화하는 매크로 상수 |
메모리 동기화 순서(Memory synchronization ordering)
| 이름 | 설명 |
|---|---|
memory_order |
(C11) 메모리 순서 제약을 정의하는 열거형 |
kill_dependency |
(C11) memory_order_consume을 위한 의존성 체인을 끊는 함수 매크로 |
atomic_thread_fence |
(C11) 범용 메모리 순서 의존 펜스 동기화 원시 연산 |
atomic_signal_fence |
(C11) 같은 스레드 내 스레드와 신호 처리기 사이의 펜스 |
편의 타입 별칭(Convenience type aliases)
typedef 이름과 전체 타입 이름을 대응시키는 표예요. 실수로 _Atomic 키워드를 빠뜨리지 않게, 편의 별칭을 쓰면 기호 사용이 훨씬 간결해져요.
| Typedef 이름 | 전체 타입 이름 |
|---|---|
atomic_bool (C11) |
_Atomic _Bool |
atomic_char (C11) |
_Atomic char |
atomic_schar (C11) |
_Atomic signed char |
atomic_uchar (C11) |
_Atomic unsigned char |
atomic_short (C11) |
_Atomic short |
atomic_ushort (C11) |
_Atomic unsigned short |
atomic_int (C11) |
_Atomic int |
atomic_uint (C11) |
_Atomic unsigned int |
atomic_long (C11) |
_Atomic long |
atomic_ulong (C11) |
_Atomic unsigned long |
atomic_llong (C11) |
_Atomic long long |
atomic_ullong (C11) |
_Atomic unsigned long long |
atomic_char8_t (C23) |
_Atomic char8_t |
atomic_char16_t (C11) |
_Atomic char16_t |
atomic_char32_t (C11) |
_Atomic char32_t |
atomic_wchar_t (C11) |
_Atomic wchar_t |
atomic_int_least8_t (C11) |
_Atomic int_least8_t |
atomic_uint_least8_t (C11) |
_Atomic uint_least8_t |
atomic_int_least16_t (C11) |
_Atomic int_least16_t |
atomic_uint_least16_t (C11) |
_Atomic uint_least16_t |
atomic_int_least32_t (C11) |
_Atomic int_least32_t |
atomic_uint_least32_t (C11) |
_Atomic uint_least32_t |
atomic_int_least64_t (C11) |
_Atomic int_least64_t |
atomic_uint_least64_t (C11) |
_Atomic uint_least64_t |
atomic_int_fast8_t (C11) |
_Atomic int_fast8_t |
atomic_uint_fast8_t (C11) |
_Atomic uint_fast8_t |
atomic_int_fast16_t (C11) |
_Atomic int_fast16_t |
atomic_uint_fast16_t (C11) |
_Atomic uint_fast16_t |
atomic_int_fast32_t (C11) |
_Atomic int_fast32_t |
atomic_uint_fast32_t (C11) |
_Atomic uint_fast32_t |
atomic_int_fast64_t (C11) |
_Atomic int_fast64_t |
atomic_uint_fast64_t (C11) |
_Atomic uint_fast64_t |
atomic_intptr_t (C11) |
_Atomic intptr_t |
atomic_uintptr_t (C11) |
_Atomic uintptr_t |
atomic_size_t (C11) |
_Atomic size_t |
atomic_ptrdiff_t (C11) |
_Atomic ptrdiff_t |
atomic_intmax_t (C11) |
_Atomic intmax_t |
atomic_uintmax_t (C11) |
_Atomic uintmax_t |
시그니처(Synopsis)
#define __STDC_VERSION_STDATOMIC_H__ 202311L
void atomic_init(volatile A* obj, /*C*/ value);
/*type*/ kill_dependency(/*type*/ y);
void atomic_thread_fence(memory_order order);
void atomic_signal_fence(memory_order order);
bool atomic_is_lock_free(const volatile A* obj);
void atomic_store(volatile A* object, /*C*/ desired);
void atomic_store_explicit(volatile A* object, /*C*/ desired, memory_order order);
/*C*/ atomic_load(const volatile A* object);
/*C*/ atomic_load_explicit(const volatile A* object, memory_order order);
/*C*/ atomic_exchange(volatile A* object, /*C*/ desired);
/*C*/ atomic_exchange_explicit(volatile A* object, /*C*/ desired, memory_order order);
bool atomic_compare_exchange_strong(volatile A* object, /*C*/* expected, /*C*/ desired);
bool atomic_compare_exchange_strong_explicit(volatile A* object, /*C*/* expected,
/*C*/ desired, memory_order success, memory_order failure);
bool atomic_compare_exchange_weak(volatile A* object, /*C*/* expected, /*C*/ desired);
bool atomic_compare_exchange_weak_explicit(volatile A* object, /*C*/* expected,
/*C*/ desired, memory_order success, memory_order failure);
/*C*/ /*atomic_fetch_key*/(volatile A* object, M operand);
/*C*/ /*atomic_fetch_key_explicit*/(volatile A* object, M operand, memory_order order);
bool atomic_flag_test_and_set(volatile atomic_flag* object);
bool atomic_flag_test_and_set_explicit(volatile atomic_flag* object,
memory_order order);
void atomic_flag_clear(volatile atomic_flag* object);
void atomic_flag_clear_explicit(volatile atomic_flag* object,
memory_order order);
여기서 A는 원자 타입, C는 그에 대응하는 비원자 타입, M은 산술·비트 연산의 피연산자 타입이에요. 실제 함수틀은 타입마다 구체화돼요. _explicit 버전은 메모리 순서(memory_order)를 직접 지정할 수 있고, 그냥 버전은 순차 일관(sequentially consistent) 순서를 사용해요.
더 알아보기
- 원자 타입의 언어 수준 의미는 원자 타입(Atomic types) 문서를 봐요.
memory_order의 자세한 의미론은 메모리 순서 문서에서 확인해요.- 스레드 자체는
<threads.h>에서 다뤄요.