?
This document uses PHP Chinese website manual Release
_Atomic ( type-name ) | (1) | (since C11) |
---|---|---|
_Atomic type-name | (2) | (since C11) |
1)用作類型說明符; 這指定了一種新的原子類型
2)用作類型限定詞; 這指定了類型名稱的原子版本。在這個角色中,它可能與 const,volatile 和 restrict混合使用),但與其他限定符不同,type-name 的原子版本可能具有不同的大小,對齊和對象表示。
type-name | - | any type other than array or function. For (1), type-name also cannot be atomic or cvr-qualified |
---|
頭<stdatomic.h>
定義37層便于使用的宏,從atomic_bool
到atomic_uintmax_t
,這簡化使用這個關(guān)鍵字與內(nèi)置和庫類型的。
_Atomic const int * p1; // p is a pointer to an atomic const intconst atomic_int * p2; // sameconst _Atomic(int) * p3; // same
原子類型的對象是唯一沒有數(shù)據(jù)競爭的對象,也就是說,它們可以被兩個線程同時修改或修改一個并被另一個線程修改。
每個原子對象都有自己的關(guān)聯(lián)修改順序,這是對該對象進(jìn)行修改的總順序。如果從某個線程的角度來看,A
某些原子M的修改發(fā)生在修改B
相同的原子 M 之前,那么按M的修改順序,A 在 B 之前發(fā)生。
請注意,雖然每個原子對象都有自己的修改順序,但它不是總順序; 不同的線程可以觀察對不同順序的不同原子對象的修改。
所有原子操作都有四種連貫性保證:
寫 - 寫連貫性:如果修改原子對象M的操作A 發(fā)生在修改M的操作B 之前,則A按修改順序M出現(xiàn)在B之前。
讀讀連貫性:如果原子對象M的值計算A在M的值計算B之前發(fā)生,并且A從M上的副作用X取其值,并且由B計算的值是由X存儲的值或者是由M上的副作用Y存儲的值,其中Y以M的修改順序比X晚出現(xiàn)。
讀寫連貫性:如果原子對象M的值計算A在M上的操作B 之前發(fā)生,則A從M上的副作用X取其值,其中X以B的修改順序出現(xiàn)在M之前。
寫讀連貫性:如果原子對象M上的副作用X 發(fā)生在 M 的值計算B 之前,則評估B從X或從修飾順序為M的X之后出現(xiàn)的副作用Y中獲取其值。
一些原子操作也是同步操作; 他們可能會有額外的釋放語義,獲取語義或順序一致的語義???code>memory_order。
內(nèi)置增量和減量運算符和復(fù)合賦值是按順序一致的順序進(jìn)行讀 - 修改 - 寫原子操作(就像使用一樣memory_order_seq_cst
)。如果需要較不嚴(yán)格的同步語義,則可以使用標(biāo)準(zhǔn)庫函數(shù)。
原子屬性只對左值表達(dá)式有意義。左值到右值轉(zhuǎn)換(將從原子位置讀到CPU寄存器的內(nèi)存建模)與其他限定符一起剝離原子性。
如果宏常量__STDC_NO_ATOMICS__
(C11)由編譯器定義,則不提供關(guān)鍵字_Atomic
和標(biāo)題<stdatomic.h>
。
訪問原子結(jié)構(gòu)/聯(lián)合的成員是未定義的行為。
庫類型sig_atomic_t
不提供線程間同步或內(nèi)存排序,只有原子性。
易失性類型不提供線程間同步,內(nèi)存排序或原子性。
_Atomic
.
#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) { ++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 10000The non-atomic counter is 8644