2010-10-04 77 views
0

在下面的代碼:Interlocked.Exchange的返回值是否也以原子方式處理?

a = Interlocked.Exchange(ref b, c); 

我知道b的設置爲C原子。但是在同樣的原子操作中是否也設置了b?或者這是在原子操作之外。

我需要的是確保a和b都在相同的原子操作中設置。

C => B,B =>一個

這是在C#.NET。

回答

2

我假設你正在考慮這樣的代碼:

using System; 
using System.Threading; 

class Test 
{ 
    static int x = 1; 
    static int y = 2; 

    static void Main() 
    { 
     x = Interlocked.Exchange(ref y, 5); 
    } 
} 

在這種情況下,沒有任何的操作不是原子操作。在IL,有兩個分開的動作:

  • 調用方法
  • 從名義堆棧的值複製到字段

,以便另一個線程「看到」 y這將是完全有可能的在Interlocked.Exchange的返回值存儲在x之前變爲5。

個人而言,如果我在看你需要多個域值的東西不可分割的方式更改,我會考慮的鎖,而不是原子無鎖操作。

+0

謝謝@Jon。這就是我所害怕的。 – IamIC 2010-10-04 13:20:51

+0

什麼(如果有)是ASM命令「XCHG」(http://siyobik.info/index.php?module=x86&id=328)的C#等效項。 用這個命令,哪個imo是一個真正的交換,我可以簡單地自動交換兩個整數,這就是我真正想要做的。 – IamIC 2010-10-04 13:23:06

+0

@IanC:說實話,我不知道那裏有*是.NET的等價物。 – 2010-10-04 13:24:51

0

Interlocked.Exchange方法(Int32,Int32)已定義:

設置一個32位帶符號整數爲指定的值,並返回原來的值,作爲一個原子操作。在MSDN文章http://msdn.microsoft.com/en-us/library/d3fxt78a.aspx

代碼示例使用Interlocked.Exchange返回碼線程安全的資源鎖定。所以,答案是肯定的,這是原子操作。

當然,如果在不同線程中運行Interlocked.Exchange並將返回值分配給同一個變量,結果可能不正確。但是這是一般的線程安全規則 - 只是使用局部變量。

+0

謝謝。 MSDN中的示例僅顯示檢查返回值。我知道交換是原子的。我不知道的是,如果將返回值設置爲變量也將是原子操作的一部分。 – IamIC 2010-10-04 13:07:37

+0

我最低限度認爲必須將其標記爲不穩定。雖然這與原子性無關。 – IamIC 2010-10-04 13:08:44

+0

不,返回值分配不是原子操作的一部分,可以在MSIL或本地程序集級別進行檢查。這只是功能的一部分。如果使用本地堆棧分配變量來保持返回值,這是安全的。 – 2010-10-04 13:32:44

相關問題