今天在知乎上看到一个问题【为何在同一进程中建立不一样线程,但线程各自的变量没法在线程间互相访问?】。在多线程中,每一个线程都是独立运行的,不一样的线程有多是同一段代码,但不会是同一做用域,因此不会共享。而共享内存,并无做用域之分,同一进程内,无论什么线程均可以经过同一虚拟内存地址来访问,不一样进程也能够经过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