atomic_fetch_add, atomic_fetch_add_explicit
|
헤더 파일에 정의됨
<stdatomic.h>
|
||
|
C atomic_fetch_add
(
volatile
A
*
obj, M arg
)
;
|
(1) | (C11 이후) |
|
C atomic_fetch_add_explicit
(
volatile
A
*
obj, M arg,
memory_order
order
)
;
|
(2) | (C11 이후) |
obj
가 가리키는 값을
arg
를
obj
의 이전 값에 더한 결과로 원자적으로 교체하고, 이전에
obj
가 보유하던 값을 반환합니다. 이 연산은 읽기-수정-쓰기 연산입니다. 첫 번째 버전은 메모리 접근을
memory_order_seq_cst
에 따라 정렬하며, 두 번째 버전은 메모리 접근을
order
에 따라 정렬합니다.
이것은 모든
generic function
에 대해 정의된
atomic object types
A
입니다. 인자는 volatile atomic 타입에 대한 포인터로, 비-volatile과
volatile
(예: 메모리 매핑된 I/O) atomic 객체들의 주소를 모두 수용하기 위함이며, volatile atomic 객체에 이 연산을 적용할 때 volatile 의미론이 유지됩니다.
M
은
A
가 atomic 정수 타입일 경우
A
에 해당하는 비-atomic 타입이거나,
A
가 atomic 포인터 타입일 경우
ptrdiff_t
입니다.
제네릭 함수의 이름이 매크로인지 외부 링크를 가진 식별자로 선언되었는지는 명시되지 않습니다. 실제 함수에 접근하기 위해 매크로 정의를 억제하는 경우(예: ( atomic_fetch_add ) ( ... ) 와 같이 괄호로 감싸는 경우), 또는 프로그램이 제네릭 함수의 이름으로 외부 식별자를 정의하는 경우, 그 동작은 정의되지 않습니다.
부호 있는 정수 타입의 경우, 산술 연산은 2의 보수 표현을 사용하도록 정의됩니다. 정의되지 않은 결과는 존재하지 않습니다. 포인터 타입의 경우, 결과가 정의되지 않은 주소일 수 있지만, 그 외의 연산에서는 정의되지 않은 동작이 없습니다.
목차 |
매개변수
| obj | - | 수정할 원자적 객체에 대한 포인터 |
| arg | - | 원자적 객체에 저장된 값에 더할 값 |
| order | - | 이 연산에 대한 메모리 동기화 순서: 모든 값이 허용됨 |
반환값
obj
가 가리키는 원자 객체가 이전에 보유하고 있던 값.
예제
#include <stdio.h> #include <threads.h> #include <stdatomic.h> atomic_int acnt; int cnt; int f(void* thr_data) { for(int n = 0; n < 1000; ++n) { atomic_fetch_add_explicit(&acnt, 1, memory_order_relaxed); // atomic ++cnt; // undefined behavior, in practice some updates missed } 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 9511
참고문헌
- C17 표준 (ISO/IEC 9899:2018):
-
- 7.17.7.5 atomic_fetch 및 modify 일반 함수 (p: 208)
- C11 표준 (ISO/IEC 9899:2011):
-
- 7.17.7.5 atomic_fetch 및 modify 일반 함수 (p: 284-285)
참고 항목
|
원자적 감산
(함수) |
|
|
C++ 문서
for
atomic_fetch_add
,
atomic_fetch_add_explicit
|
|