Atomic types
목차 |
구문
_Atomic
(
type-name
)
|
(1) | (C11부터) | |||||||
_Atomic
type-name
|
(2) | (C11부터) | |||||||
const
,
volatile
, 그리고
restrict
와 혼합하여 사용할 수 있지만, 다른 한정자들과 달리
type-name
의 atomic 버전은 다른 크기, 정렬 및 객체 표현을 가질 수 있습니다.
| type-name | - | 배열이나 함수가 아닌 모든 타입. (1) 의 경우, type-name 은 atomic이나 cvr-qualified일 수 없음 |
헤더 파일 <stdatomic.h> 는 다양한 편의성 타입 별칭들 을 정의합니다. atomic_bool 부터 atomic_uintmax_t 까지의 이러한 별칭들은 내장 타입과 라이브러리 타입에서 이 키워드의 사용을 단순화합니다.
_Atomic const int* p1; // p는 atomic const int를 가리키는 포인터입니다 const atomic_int* p2; // 동일 const _Atomic(int)* p3; // 동일
매크로 상수 __STDC_NO_ATOMICS__ 가 컴파일러에 의해 정의된 경우, _Atomic 키워드는 제공되지 않습니다.
설명
원자적 타입의 객체들은 데이터 레이스 로부터 자유로운 유일한 객체입니다; 즉, 두 스레드에 의해 동시에 수정되거나 하나의 스레드에 의해 수정되고 다른 스레드에 의해 읽힐 수 있습니다.
각 원자 객체는 해당 객체에 대한 수정들의 전체 순서인 자체
수정 순서(modification order)
를 가집니다. 만약 어떤 스레드의 관점에서, 특정 원자 객체
M
의 수정
A
가 동일한 원자 객체
M
의 수정
B
보다
happens-before
관계에 있다면,
M
의 수정 순서에서
A
는
B
보다 앞서 발생합니다.
각 원자 객체는 자체적인 수정 순서를 가지지만, 단일한 전체 순서는 존재하지 않습니다. 서로 다른 스레드들은 서로 다른 원자 객체들에 대한 수정 사항을 다른 순서로 관찰할 수 있습니다.
모든 원자적 연산에 대해 보장되는 네 가지 일관성 종류가 있습니다:
-
write-write coherence
: 원자적 객체
M을 수정하는 연산A가M을 수정하는 연산B보다 happens-before 관계에 있다면,M의 수정 순서에서A가B보다 먼저 나타납니다. -
read-read coherence
: 원자적 객체
M의 값 계산A가M의 값 계산B보다 happens before 관계에 있고,A가M에 대한 사이드 이펙트X로부터 값을 가져온다면,B에 의해 계산된 값은X에 의해 저장된 값이거나,M의 수정 순서에서X보다 나중에 나타나는 사이드 이펙트Y에 의해 저장된 값입니다. -
read-write coherence
: 원자적 객체
M의 값 계산A가M에 대한 연산B보다 happens-before 관계에 있다면,A는M의 수정 순서에서B보다 먼저 나타나는 사이드 이펙트X로부터 값을 가져옵니다. -
write-read coherence
: 원자적 객체
M에 대한 사이드 이펙트X가M의 값 계산B보다 happens-before 관계에 있다면,B평가는X로부터 값을 가져오거나,M의 수정 순서에서X보다 나중에 나타나는 사이드 이펙트Y로부터 값을 가져옵니다.
일부 원자적 연산은 동기화 연산이기도 합니다; 여기에는 추가적인 릴리스 의미론, 획득 의미론 또는 순차적 일관성 의미론이 있을 수 있습니다. memory_order 를 참조하십시오.
내장 증가 및 감소 연산자 와 복합 할당 연산자 는 완전한 순차적 일관성 순서를 갖는 읽기-수정-쓰기 원자 연산입니다 ( memory_order_seq_cst 를 사용하는 것처럼). 덜 엄격한 동기화 의미론이 필요한 경우, 대신 표준 라이브러리 함수 를 사용할 수 있습니다.
원자적 속성은 lvalue 표현식 에 대해서만 의미가 있습니다. Lvalue-to-rvalue 변환(원자적 위치에서 CPU 레지스터로의 메모리 읽기를 모델링함)은 다른 한정자와 함께 원자성을 제거합니다.
|
이 섹션은 불완전합니다
이유: 추가 검토 필요, memory_order 및 atomic 라이브러리 페이지와의 상호작용 검토 |
참고 사항
원자적 구조체/공용체의 멤버에 접근하는 것은 정의되지 않은 동작입니다.
라이브러리 타입 sig_atomic_t 는 스레드 간 동기화나 메모리 정렬을 제공하지 않으며, 원자성만을 제공합니다.
volatile
타입은 스레드 간 동기화, 메모리 정렬 또는 원자성을 제공하지 않습니다.
구현체는 C 언어의
_Atomic
(
T
)
표현이 모든 가능한 타입
T
에 대해 C++의
std
::
atomic
<
T
>
표현과 동일하도록 보장하는 것이 권장됩니다. 원자성과 메모리 순서를 보장하는 메커니즘은 상호 호환되어야 합니다.
키워드
예제
#include <stdatomic.h> #include <stdio.h> #include <threads.h> atomic_int acnt; int cnt; int f(void* thr_data) { for (int n = 0; n < 1000; ++n) { ++cnt; ++acnt; // for this example, relaxed memory order is sufficient, e.g. // atomic_fetch_add_explicit(&acnt, 1, memory_order_relaxed); } return 0; } int main(void) { thrd_t thr[10]; for (int n = 0; n < 10; ++n) thrd_create(&thr[n], f, NULL); for (int n = 0; n < 10; ++n) thrd_join(thr[n], NULL); printf("The atomic counter is %u\n", acnt); printf("The non-atomic counter is %u\n", cnt); }
가능한 출력:
The atomic counter is 10000 The non-atomic counter is 8644
참고문헌
- C23 표준 (ISO/IEC 9899:2024):
-
- 6.7.2.4 Atomic type specifiers (p: TBD)
-
- 7.17 Atomics <stdatomic.h> (p: TBD)
- C17 표준 (ISO/IEC 9899:2018):
-
- 6.7.2.4 Atomic type specifiers (p: 87)
-
- 7.17 Atomics <stdatomic.h> (p: 200-209)
- C11 표준 (ISO/IEC 9899:2011):
-
- 6.7.2.4 Atomic type specifiers (p: 121)
-
- 7.17 Atomics <stdatomic.h> (p: 273-286)
참고 항목
| 동시성 지원 라이브러리 | |
|
C++ documentation
for
atomic
|