atomic_fetch_add, atomic_fetch_add_explicit
提供: cppreference.com
ヘッダ <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
の指す値を obj
の古い値に arg
を加算した結果にアトミックに置き換え、 obj
がそれまで保持していた値を返します。 この操作は読み込み-変更-書き込み操作です。 1つめのバージョンは memory_order_seq_cst に従ってメモリアクセスを順序付けし、 2つめのバージョンは order
に従ってメモリアクセスを順序付けします。
これはすべてのアトミックオブジェクト型 A
に対して定義される総称関数です。 引数は非 volatile と volatile (メモリマップド I/O など) 両方のアトミック変数のアドレスを受理するための volatile アトミック型へのポインタです。
M
は A
がアトミック整数型の場合は A
に対応する非アトミック型、 A
がアトミックポインタ型の場合は ptrdiff_t です。
符号付き整数型の場合、算術は2の補数表現を用いて定義されます。 未定義の結果はありません。 ポインタ型の場合、結果が未定義のアドレスとなる場合はありますが、それ以外で演算に未定義動作はありません。
目次 |
[編集] 引数
obj | - | 変更するアトミックオブジェクトを指すポインタ |
arg | - | アトミックオブジェクトに格納されている値に加算する値 |
order | - | この操作に対するメモリ同期順序付け。 すべての値を指定できます |
[編集] 戻り値
obj
の指すアトミックオブジェクトがそれまで保持していた値。
[編集] 例
Run this code
#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
[編集] 参考文献
- C11 standard (ISO/IEC 9899:2011):
- 7.17.7.5 The atomic_fetch and modify generic functions (p: 284-285)
[編集] 関連項目
アトミックな減算 (関数) | |
atomic_fetch_add, atomic_fetch_add_explicit の C++リファレンス
|