本机配置
i7CPU四核八线程
并行开发的概念
并行开发要做的事情就是将任务分摊给硬件线程去并行执行来达到负载和加速,传统的代码都是串行的,就一个主线程,当我们为了实现加速而开了很多工作线程,这些工作线程就是软件线程
Parallel的使用
Parallel类是对线程的抽象,位于System.Threading.TasKs名称空间下,提供了任务和数据并行性.在Parallel下有三个常用的方法Invoke,For和ForEach,其中Parallel.Invoke用于任务并行性,Parallel.ForEach用于数据并行性
Parallel.Invoke
如果多个任务应并行运行,就可以使用Parallel.Invoke()方法,可以最简单,最简洁的将串行的代码并行化
class ThreadTest { static void Main(string[] args) { var watch = Stopwatch.StartNew(); watch.Start(); Run1(); Run2(); Run3(); watch.Stop(); Console.WriteLine("串行开发,总耗时{0}", watch.ElapsedMilliseconds); watch.Restart(); Parallel.Invoke(Run1, Run2, Run3); watch.Stop(); Console.WriteLine("并行开发,总耗时{0}", watch.ElapsedMilliseconds); Console.ReadKey(); } static void Run1() { Console.WriteLine("Run1,我需要1s"); Thread.Sleep(1000); } static void Run2() { Console.WriteLine("Run2,我需要3s"); Thread.Sleep(3000); } static void Run3() { Console.WriteLine("Run3,我需要4s"); Thread.Sleep(4000); } }
主程序启动时,先顺序调用Run1(),Run()2,Run3()方法,这是串行的,而后使用Parallel.Invoke()将三个方法并行调用,可见耗时是有明显提升的
Parallel.For
串行代码中也有一个for,但是那个for并没有用到多核,而Paraller.for它会在底层根据硬件线程的运行状况来充分的使用所有的可利用的硬件线程
static void Main(string[] args) { for (int i = 0; i < 3; i++) { ConcurrentBag<int> bag = new ConcurrentBag<int>(); var watch = Stopwatch.StartNew(); watch.Start(); for (int j = 0; j < 20000000; j++) { bag.Add(i); } watch.Stop(); Console.WriteLine("串行添加,总数20000000,耗时{0}", watch.ElapsedMilliseconds); GC.Collect(); watch.Restart(); Parallel.For(0, 20000000, j => { bag.Add(j); }); watch.Stop(); Console.WriteLine("并行添加,总数20000000,耗时{0}", watch.ElapsedMilliseconds); Console.WriteLine("***********************************"); GC.Collect(); } Console.ReadKey(); }
向一个线程安全的集合插入数据,使用串行的for耗时与使用并行的Parallel.For差异
Parallel.For提前中断
Parallel.ForEach
ForEach的特点在于可以将数据进行分区,每一个小区内实现串行计算,分区采用Partitioner.Create实现