2010-03-31 53 views
5

我假設在像iPhone這樣的32位設備上,分配一個短浮點是一個原子線程安全的操作。我想確保它是。我有我想從一個Objective-C線程調用C函數,而我不希望調用它之前獲得鎖:是單浮動分配在iPhone上的原子操作?

void setFloatValue(float value) { 
    globalFloat = value; 
} 

回答

5

在32位ARM,上面的函數會被編譯到

ldr r2, [pc, #0x??] ; to retrieve the address of globalFloat 
str r0, [r2]   ; store value into globalFloat 

由於有2個指令,並且CPU可以自由地在它們之間進行任何東西,但只有第二指令str r0, [r2]影響記憶。除非globalFloat未對齊,CPU可以對其執行單拷貝原子寫入。

當全局指針未對齊時,賦值可以是非原子的。如果你正在寫一個更大的結構,例如它也是非原子的。的CGRect。

對於線程安全來說,原子是不夠的。由於緩存和指令重新排序,您的更改可能對其他CPU內核不可見。您可能需要插入OSMemoryBarrier()以「發佈」更改。

當涉及複合操作時(例如globalFloat += value),原子操作通常很有趣。你可能想看看它的內置OSAtomic庫。

+0

但這仍然是 「有點兒八九不離十原子」,在全球國家的實際寫入是一個單一的指令,所以沒有人看到globalFloat可以在中間狀態下看到它。 – unwind 2010-03-31 07:02:39

+2

沒有一個用於分配。 – 2010-03-31 07:02:48

+0

@unwind:任何商店指令都是如此。這裏的中間狀態是在它被讀取之後並且在它被寫入之前,當變量物理地存在於兩個地方(存儲器和寄存器)時。 – Potatoswatter 2010-03-31 07:06:57

3

是的,它會是原子的。在32位體系結構上,對32位或更小(char,short,int,long,float等)基本數據類型的任何存儲操作都將是原子操作。