我想從多個線程增加一個無符號整數。C#多線程無符號增量
我知道Interlocked.Increment,但它不處理無符號整數。我可以使用lock(),但如果可能出於性能原因,我寧願不使用。
它是線程安全的,只是以正常的方式增加它?偶爾增加的數據丟失並不重要,因爲它僅用於統計數據。我不想要的是損壞的價值。
我想從多個線程增加一個無符號整數。C#多線程無符號增量
我知道Interlocked.Increment,但它不處理無符號整數。我可以使用lock(),但如果可能出於性能原因,我寧願不使用。
它是線程安全的,只是以正常的方式增加它?偶爾增加的數據丟失並不重要,因爲它僅用於統計數據。我不想要的是損壞的價值。
你可以聲明uint爲volatile。
http://msdn.microsoft.com/en-us/library/x13ttww7(VS.71).aspx
如果你真的需要全方位unsigned int型的(2^32 - 1),而不是一個有符號整數(2^231-1),你可以轉換爲64位整數(有一個Interlocked.Increment
需要int64的重載),然後轉換回unsigned int。
你說你不想使用lock
出於性能的原因 - 但你測試過嗎?一個無爭議的鎖(這可能是,它的聲音)是相當便宜。
當談到線程化(通常,但特別是線程化)時,我通常會選擇「明顯正確」,而不是「聰明並可能更好地執行」。
基準測試你的應用有無鎖定,看看你是否能夠注意到它們之間的差異。如果鎖定造成顯着差異,那麼確定使用狡猾的東西。否則,我只是堅持一個鎖。
一個你可能想要做的事情是使用Interlocked.Increment
與int
和只投它在必要時獲得uint
,像這樣:
using System;
using System.Reflection;
using System.Threading;
public class Test
{
private static int count = int.MaxValue-1;
public static uint IncrementCount()
{
int newValue = Interlocked.Increment(ref count);
return (uint) newValue;
}
public static void Main()
{
Console.WriteLine(IncrementCount());
Console.WriteLine(IncrementCount());
Console.WriteLine(IncrementCount());
}
}
輸出:
2147483647
2147483648
2147483649
(換句話說,它沒有任何問題。)
這隻能確保對v可變的會立即寫回到內存中,而不是等待線程退出或寄存器中的值被移位。它不保護對現場的訪問,即兩個(或更多)線程可以讀取相同的值,遞增一次,然後寫回,從而有效地將值增加1. – 2009-06-01 12:42:49
請閱讀上述要求以及 http: //msdn.microsoft.com/en-us/library/7a2f3ay4.aspx。 對於給定的情況就足夠了。 – Sesh 2009-06-01 15:00:23
與Interlocked.Increment相比,性能如何變化?相同?更好? – jrista 2009-06-07 02:08:42