2016-01-11 61 views
1

如果我理解正確,應該使用OSAtomicIncrement64以原子方式增加一個變量。使用下面的一種或另一種方案有什麼區別/優勢?OSAtomicIncrement64 x類屬性...有什麼優勢?

方案1

@interface MyClass : NSObject { 
    __block volatile int64_t variable; 
} 

OSAtomicIncrement64(&variable); 

一個塊內或

方案2

@interface MyClass : NSObject 
    @property(atomic, assign) int64_t variable; 

self.variable++; 

塊裏面?

回答

2

首先,將__block屬性添加到實例變量不起作用;在任何情況下,變量都可以從塊中修改。

其次,volatile在這裏沒有真正的區別。這告訴編譯器它不能假定該值是穩定的,並在彙編(機器)級別重新排序內存操作時使用。它不影響變量的原子性。

第三,實例變量和屬性之間的區別在於屬性對於讀取和寫入都是原子的。實例變量的更新對於寫入來說只是原子的(在你的例子中),儘管對於讀取來說它也是原子的也是微不足道的。

這事項在以下情形:

  • 32位硬件
  • 讀取64位值的

步驟:

  1. 線程1點開始負荷,讀取32位
  2. 線程2原子更新值
  3. 線程1負載其他32位

如果讀取是非原子,上述場景可能發生。如果讀取是原子性的,則步驟2將在1或3之後(取決於時間)發生,並且在任一情況下將讀取正確的值。

+0

我已經意識到了發佈之後的volatile和__block部分。小心澄清你最後的短語? *該屬性對於閱讀也是原子性的,但是如果寫入是原子性的,那麼這通常不是問題。* – SpaceDog

+0

好吧,我想不出任何例子,如果寫入是原子性的,非原子讀取會成爲問題,但我沒有我不想寫一個絕對的,因爲可能會有一些。 – Avi

+0

其實,沒關係。這個例子很明顯:讀一半的64位數字,讓一個寫作者自動更新它,讀另一半。繁榮! – Avi