C#中多線程中變量研究

今天在知乎上看到一個問題【爲何在同一進程中建立不一樣線程,但線程各自的變量沒法在線程間互相訪問?】。在多線程中,每一個線程都是獨立運行的,不一樣的線程有多是同一段代碼,但不會是同一做用域,因此不會共享。而共享內存,並無做用域之分,同一進程內,無論什麼線程均可以經過同一虛擬內存地址來訪問,不一樣進程也能夠經過ipc等方式共享內存數據。全局變量:任何線程均可以訪問;局部變量(棧變量):任何線程執行到該函數時都可訪問,函數外不可訪問;線程變量:每一個線程只能訪問本身的那個拷貝,其餘線程不可見。今天就用C#來實現同一段代碼的不一樣線程,全局變量、局部變量、線程變量。html

瞭解進程與線程

什麼是多任務,簡單來講就是操做系統同時能夠運行多個任務。例如:一遍聽歌,一遍寫文檔等。多核CPU能夠執行多任務,可是單核CPU也能夠執行多任務,CPU是順序執行的,操做系統讓任務輪流執行,例如:聽歌執行一次,停頓0.01s,寫文檔執行一次,停頓0.01s等等。因爲CPU的執行速度很快,咱們感受就像全部的任務都是同時執行。對操做系統來講,一個任務就是一個進程,一個進程至少有一個線程。進程是資源分配的最小單位,線程是CPU調度的最小單位。安全

普通的程序寫法

private static List<int> data = Enumerable.Range(1, 1000).ToList();

public static void SimpleTest()
{
    for (int i = 0; i < 10; i++)
    {
        List<int> tempData = new List<int>();
        foreach (var d in data)
        {
            tempData.Add(d);
        }
        Console.WriteLine($"i:{i},合計:{data.Sum()},是否相等:{data.Sum() == tempData.Sum()}");
    }

    Console.WriteLine("單線程運行結束");
}

多線程寫法

private static List<int> data = Enumerable.Range(1, 1000).ToList();

public static async Task MoreTaskTestAsync()
{
    List<Task> tasks = new List<Task>();
    for (int i = 0; i < 10; i++)
    {
        var tempi = i;
        var t = Task.Run(() =>
        {
            List<int> tempData = new List<int>();
            foreach (var d in data)
            {
                tempData.Add(d);
            }
            Console.WriteLine($"i:{tempi},合計:{data.Sum()},是否相等:{data.Sum() == tempData.Sum()}");
        });
        tasks.Add(t);
    }

    await Task.WhenAll(tasks); //或者Task.WaitAll(tasks.ToArray());
    Console.WriteLine("多線程運行結束");
}

不一樣的線程同一段代碼,但不會是同一做用域,因此tempData數據沒有互相影響。多線程

全局變量:data,多個線程均可以訪問,list只讀的時候是線性安全
局部變量:i就是局部變量,訪問的線程能夠訪問,去掉【var tempi = i;】,運行結果打印出來,值都是同樣的,增長的都是每一個線程都訪問單獨的tempi變量async

i:10,合計:500500,是否相等:True
i:10,合計:500500,是否相等:True
i:10,合計:500500,是否相等:True
i:10,合計:500500,是否相等:True
i:10,合計:500500,是否相等:True
i:10,合計:500500,是否相等:True
i:10,合計:500500,是否相等:True
i:10,合計:500500,是否相等:True
i:10,合計:500500,是否相等:True
i:10,合計:500500,是否相等:True

線程變量:tempData,每一個線程只訪問本身的,互不影響,運行結果函數

i:3,合計:500500,是否相等:True
i:6,合計:500500,是否相等:True
i:0,合計:500500,是否相等:True
i:1,合計:500500,是否相等:True
i:4,合計:500500,是否相等:True
i:2,合計:500500,是否相等:True
i:7,合計:500500,是否相等:True
i:5,合計:500500,是否相等:True
i:8,合計:500500,是否相等:True
i:9,合計:500500,是否相等:True

寫多線程的時候須要注意,變量的做用域,不然程序運行出來的結果將不會是想要的結果,注意,注意變量做用域。優化

其餘的多線程文章

1. C#中await/async閒說spa

2. .NET中並行開發優化操作系統

3. C# Task.Run 和 Task.Factory.StartNew 區別線程

4. C#中多線程的並行處理code

相關文章
相關標籤/搜索