2010-02-14 17 views
7

當兩個線程同時將BOOL設置爲YES時會發生什麼?BOOL是否在Objective C中讀/寫原子?

+16

它打開了一個蟲洞到另一個層面。 – dreamlax 2010-02-14 02:44:07

+5

如果他們倆都將它設置爲'YES',不可能有問題無論寫的是否是原子的,都可以在那裏? – 2010-02-14 02:47:27

+0

@CarlNorum可能是真的,但它對我來說並不明顯爲什麼 – 2016-12-12 16:16:35

回答

6

號沒有一個鎖定結構,讀/寫的任何類型的變量沒有在目標C

原子如果兩個線程同時爲BOOL寫YES,結果無論是哪一個得到是YES在第一。

請參閱:Synchronizing Thread Execution

+2

謝謝,Mitch。如果一個thr ead將其設置爲YES,而另一個設置爲NO時,是否會出現內存損壞? – Jacko 2010-02-14 03:25:16

+1

http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html給出了一個非常全面的討論。我想我將使用int而不是BOOL,並在此int上使用OSAtomic操作。 – Jacko 2010-02-14 03:33:59

+0

你的問題的含義是否可能會摧毀其他一些內存塊。沒有;那不可能發生。會發生的最糟糕的情況是,在另一個線程中寫入YES後,您會看到NO。 – bbum 2010-02-14 06:59:46

7

下面是Jacko建議的解決方案代碼。
使用volatileuint32_tOSAtomicOr32BarrierOSAtomicAnd32Barrier

#import <libkern/OSAtomic.h> 

volatile uint32_t _IsRunning; 

- (BOOL)isRunning { 
    return _IsRunning != 0; 
} 

- (void)setIsRunning:(BOOL)allowed { 

    if (allowed) { 
     OSAtomicOr32Barrier(1, & _IsRunning); //Atomic bitwise OR of two 32-bit values with barrier 
    } else { 
     OSAtomicAnd32Barrier(0, & _IsRunning); //Atomic bitwise AND of two 32-bit values with barrier. 
    } 
} 
+0

酷!但爲什麼不使用'OSAtomicOr32Barrier(允許,&_IsRunning);'而不是條件語句? – 2014-07-21 06:28:03

+0

是的,你可以使用。 – 2014-07-21 06:36:19

+0

啊,不是那麼簡單,對不起。您不能使用「或」版本來重置標誌,即您必須使用「和」版本來執行此操作(OSAtomicAnd32Barrier)。 – 2014-07-21 06:43:39

3

我會從接受的答案出現分歧。抱歉。 雖然objective c不能保證聲明爲非原子的BOOL屬性實際上是原子的,但我不得不猜測你最關心的硬件(所有iOS和macos設備)都有指令來自動執行字節讀取和存儲。因此,除非蘋果公司在具有5位總線寬度的IBM微控制器上運行 以在 上發送10位字節,否則您可以在需要原子BOOL的情況下使用非原子BOOL。該代碼不能移植到Road Light OS,但如果你可以犧牲代碼的未來安全性,那麼非原子對於這個用例來說是很好的。 我敢肯定,s.o上有很多人。這將引發對分解原子/非原子情況下合成的BOOL獲取器和設置器的挑戰,以查看有什麼不同。至少在ARM上。

你從這個外賣很可能在

  1. 你可以聲明BOOL屬性原子和它不會花費你一毛錢 上的所有硬件的iOS和MacOS內在支持。
  2. 記憶障礙是垂直於原子
  3. 你最絕對不應該使用4個字節的屬性布爾值存入 除非你進入[十分]模糊邏輯。 這是愚蠢的和浪費的,你不想成爲一個Java程序員的克隆人, 誰不能從一個雙浮動浮動,或者你呢?
  4. BOOL變量(其不顯着支持原子/非原子裝飾 不會在對一些窄的總線體系結構的目標C將 不能反正用在原子(有或沒有一些[非常]微OS微控制器是C &組件領土我想,他們通常不需要行李 objc運行時會帶來)
相關問題