我有以下代碼:C#多線程和重新排序 - 這裏發生了什麼?
public static System.Int32 i = 0;
static void Main(string[] args)
{
new Thread(Worker1) { IsBackground = true }.Start();
new Thread(Worker2) { IsBackground = true }.Start();
Console.WriteLine("Running... Press enter to quit");
Console.ReadLine();
}
static void Worker1(object _)
{
while (true)
{
var oldValue = i;
i++;
var newValue = i;
if (newValue < oldValue)
Console.WriteLine("{2}, i++ went backwards! oldValue={0}, newValue={1}!", oldValue, newValue, DateTime.Now.ToString("HH:MM:ss.fff"));
}
}
static void Worker2(object _)
{
while (true)
{
i++;
}
}
運行時,這會產生輸出看起來像這樣:
17:08:17.020, i++ went backwards! oldValue=6124653, newValue=6113984!
17:08:17.057, i++ went backwards! oldValue=18764535, newValue=18752368!
17:08:17.086, i++ went backwards! oldValue=27236177, newValue=27236176!
17:08:17.087, i++ went backwards! oldValue=27550457, newValue=27535008!
17:08:17.130, i++ went backwards! oldValue=40251349, newValue=40235492!
17:08:17.137, i++ went backwards! oldValue=42339974, newValue=42323786!
17:08:17.142, i++ went backwards! oldValue=43828602, newValue=43828436!
17:08:17.149, i++ went backwards! oldValue=45969702, newValue=45959111!
17:08:17.158, i++ went backwards! oldValue=48705847, newValue=48705549!
17:08:17.230, i++ went backwards! oldValue=71199684, newValue=71199674!
注:這是一個四核i7超線程在Windows 7中運行
至於我可以告訴大家,無論是:
線程2在我讀取oldValue和newValue之間遞增約40億次(但不完全!)。但是,考慮到上面的數字和時間安排,似乎我在接下來的2秒內有10次獲得彩票的機會更高。
CPU和編譯器正在做一些重新排序...這似乎是合乎邏輯的解釋,但我不能完全弄清楚可能會導致這種情況的一系列操作?
任何人都可以看到它嗎?
爲了澄清問題:我故意尋找代碼來重現內存重新排序錯誤作爲教育練習的一部分。有很多方法可以解決這個問題,我主要對分析發生的事情感興趣。
@Tymek在下面顯示了(明顯是顯而易見的,現在指出)。
它只是可能發生,操作系統需要一些資源,而執行您的程序,這導致了一種重新排序的感覺。只要期望通過多線程和多個非同步操作,每個可能的排列都會發生 - 遲早會發生。 – weismat 2012-08-02 06:23:05