Home [C# 筆記] Threading - C# Thread Synchronization Issue
Post
Cancel

[C# 筆記] Threading - C# Thread Synchronization Issue

C# Thread Synchronization Issue

Thread 看起來是同步,但事實上是在相互搶資源…

前置準備:讓三個執行緒可以很乾淨的遞增

寫一個範例,讓三個執行緒可以很乾淨的遞增…

現在總共有三個執行緒,一個是主執行緒Main(),另外兩個是新建立的thread1thread2執行緒。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
internal class Program
{
    static int count = 0;
    static void Main(string[] args)
    {
        //建立兩個執行緒,讓它們都進入IncrementCount方法
        var thread1 = new Thread(IncrementCount);
        var thread2 = new Thread(IncrementCount);

        thread1.Start();
        Thread.Sleep(500); //讓主執行緒不同步半秒
        thread2.Start();
    }

    static void IncrementCount()
    {
        while (true)
        {
            count++;
            //做一個有趣的輸出
            Console.WriteLine($"Thread ID: {Thread.CurrentThread.ManagedThreadId} incremented count to: {count}");
            Thread.Sleep(1000); //讓執行緒睡眠1000毫秒(讓程式暫停一秒)
        }
    }
}

執行結果:

控制台輸出 託管的 Thread ID 和很乾淨的 Count 遞增。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Thread ID: 10 incremented count to: 1
Thread ID: 11 incremented count to: 2
Thread ID: 11 incremented count to: 3
Thread ID: 10 incremented count to: 4
Thread ID: 10 incremented count to: 5
Thread ID: 11 incremented count to: 6
Thread ID: 11 incremented count to: 7
Thread ID: 10 incremented count to: 8
Thread ID: 11 incremented count to: 9
Thread ID: 10 incremented count to: 10
Thread ID: 11 incremented count to: 11
Thread ID: 10 incremented count to: 12
Thread ID: 11 incremented count to: 13
Thread ID: 10 incremented count to: 14
Thread ID: 11 incremented count to: 15
Thread ID: 10 incremented count to: 16
Thread ID: 11 incremented count to: 17

模擬互相爭奪搶資源的情境

再改一下程式,可以看出他們互相爭奪搶資源的情境…

count++看起來像是一個操作,但事實上不是,其實它背後做了很多事,會執行很多步驟。
count++….count=count+1

修改一下,再讓主執行緒大量的睡一下,把差距拉大…
(一秒和半秒對計算機來說,是很長的時間…)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
internal class Program
{
    static int count = 0;
    static void Main(string[] args)
    {
        //建立兩個執行緒,讓它們都進入IncrementCount方法
        var thread1 = new Thread(IncrementCount);
        var thread2 = new Thread(IncrementCount);

        thread1.Start();
        Thread.Sleep(500); //讓主執行緒不同步半秒
        thread2.Start();
    }

    static void IncrementCount()
    {
        while (true)
        {
            int temp = count;
            Thread.Sleep(500); //讓主執行緒睡半秒
            count = temp + 1;

            //做一個有趣的輸出
            Console.WriteLine($"Thread ID: {Thread.CurrentThread.ManagedThreadId} incremented count to: {count}");
            Thread.Sleep(1000); //讓執行緒睡眠1000毫秒(讓程式暫停一秒)
        }
    }
}

執行結果:

會發現控制台有非常糟糕的輸出,count不再井然有序,會出現重複的 count值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Thread ID: 9 incremented count to: 1
Thread ID: 10 incremented count to: 2
Thread ID: 9 incremented count to: 3
Thread ID: 10 incremented count to: 4
Thread ID: 9 incremented count to: 5
Thread ID: 10 incremented count to: 5
Thread ID: 9 incremented count to: 6
Thread ID: 10 incremented count to: 6
Thread ID: 9 incremented count to: 7
Thread ID: 10 incremented count to: 8
Thread ID: 9 incremented count to: 9
Thread ID: 10 incremented count to: 9
Thread ID: 9 incremented count to: 10
Thread ID: 10 incremented count to: 10
Thread ID: 9 incremented count to: 11
Thread ID: 10 incremented count to: 11

C# Thread Synchronization Issue

This post is licensed under CC BY 4.0 by the author.