今天在知乎上看到一個問題【爲何在同一進程中建立不一樣線程,但線程各自的變量沒法在線程間互相訪問?】。在多線程中,每一個線程都是獨立運行的,不一樣的線程有多是同一段代碼,但不會是同一做用域,因此不會共享。而共享內存,並無做用域之分,同一進程內,無論什麼線程均可以經過同一虛擬內存地址來訪問,不一樣進程也能夠經過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