簡體   English   中英

gcc 原子內置函數

[英]gcc atomic built-in functions

http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Atomic-Builtins.html

我相信以下代碼會原子地增加 var 的值。

volatile int var = 0;
__sync_fetch_and_add( &var, 1 )

我將上述代碼理解為以下邏輯

  1. 加載變量 var 的地址
  2. 以某種方式將數字 1 原子地寫入變量 var - 通過寄存器/緩存

但是,我懷疑以下內容是否也是原子的

volatile int var = 0;
volatile int num = 1;
__sync_fetch_and_add( &var, num )

因為它可能被解釋為

  1. 加載變量 var 的地址
  2. 將變量 num 的值加載到寄存器中
  3. 將值寫入變量 var。

在 #2 執行之后,但在 #3 之前,CPU/線程被中斷,另一個 CPU/線程更新變量 num 的值。

換句話說,當使用 gcc 的_sync *() 時,我可以使用變量而不是常量作為第二個參數嗎?

它不會破壞原子性嗎?

該操作實際上是兩個操作。

__sync_fetch_and_add( &var, num )

加載num是原子的。 將其添加到var是原子的。 但是兩個原子操作放在一起時不會產生原子操作。 這就是為什么發明新的無鎖數據結構如此困難的原因。 一般來說,兩個線程安全的操作在組合時不一定構成一個線程安全的操作。 這就是制作正確的多線程應用程序如此困難的原因。

你看, __sync_fetch_and_add確實是原子的,但它的行為就像一個普通的 function —— 所以它把“num”的當前值作為參數。 說 function 的原子性被破壞是不完全正確的——因為從num加載值是調用者的責任,它不是函數接口的一部分。 我同樣可以抱怨這一點:

__sync_fetch_and_add(&var, some_really_long_function());

或者更糟的是,

__sync_fetch_and_add(long_function_1(), long_function_2());

你說它“可能被解釋為”

  1. 加載變量 var 的地址
  2. 加載變量 num 的值
  3. 執行原子加法

但是根據C規范,並不是說可以這樣解釋,而是一定要這樣解釋,否則編譯器會不一致(其實可以互換#1和#2,但這並不重要這里)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM