并行编程多线程之Parallel
1、简介
随着多核时代的到来,并行开发越来越展示出它的强大威力!使用并行程序,充分的利用系统资源,提高程序的性能。在.net 4.0中,微软给我们提供了一个新的命名空间:System.Threading.Tasks。
2、测试类
using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace Parallel学习 { class ParallelDemo { private Stopwatch stopWatch = new Stopwatch(); private void run1() { Thread.Sleep(2000); Console.WriteLine("Task 1 is cost 2 sec"); } private void run2() { Thread.Sleep(3000); Console.WriteLine("Task 2 is cost 3 sec"); } public void ParallelInvokeMethod() { stopWatch.Start(); Parallel.Invoke(run1, run2); stopWatch.Stop(); Console.WriteLine("Parallel run " + stopWatch.ElapsedMilliseconds + " ms."); stopWatch.Restart(); run1(); run2(); stopWatch.Stop(); Console.WriteLine("Parallel run " + stopWatch.ElapsedMilliseconds + " ms."); } public void parallelForMethod() { stopWatch.Start(); for (int i = 0; i < 10000; i++) { for (int j = 0; j < 60000; j++) { int sum = 0; sum += 1; } } stopWatch.Stop(); Console.WriteLine("NormalFor run " + stopWatch.ElapsedMilliseconds + " ms."); stopWatch.Reset(); stopWatch.Restart(); Parallel.For(0, 10000, item => { for (int i = 0; i < 60000; i++) { int sum = 0; sum += item; } }); stopWatch.Stop(); Console.WriteLine("ParallelFor run " + stopWatch.ElapsedMilliseconds + " ms."); } /// <summary> /// 出现抢夺资源状况下的Parallel.For方法,这主要是由于并行同时访问全局变量,会出现资源争夺,大多数时间消耗在了资源等待上面。 /// </summary> public void parallelForMethod2() { int sum = 0; var obj = new object(); stopWatch.Start(); for (int i = 0; i < 10000; i++) { for (int j = 0; j < 60000; j++) { sum++; } } stopWatch.Stop(); Console.WriteLine("NormalFor run " + stopWatch.ElapsedMilliseconds + " ms."); stopWatch.Reset(); stopWatch.Restart(); Parallel.For(0, 10000, item => { for (int i = 0; i < 60000; i++) { //对全局变量加锁,防止抢夺出现错误 lock (obj) { sum++; } } }); stopWatch.Stop(); Console.WriteLine("ParallelFor run " + stopWatch.ElapsedMilliseconds + " ms."); } public void parallelForeach() { List<int> list = new List<int>(); list.Add(0); list.Add(1); list.Add(2); list.Add(3); Parallel.ForEach(list, item => { item++; Console.WriteLine(item.ToString()); }); } public void Run1() { Thread.Sleep(2000); Console.WriteLine("Task 1 is cost 2 sec"); throw new Exception("Exception in task 1"); } public void Run2() { Thread.Sleep(3000); Console.WriteLine("Task 2 is cost 3 sec"); throw new Exception("Exception in task 2"); } public void ParallelBreak() { ConcurrentBag<int> bag = new ConcurrentBag<int>(); stopWatch.Start(); Parallel.For(0, 1000, (i, state) => { if (bag.Count == 300) { state.Stop();//这里使用的是Stop,当数量达到300个时,会立刻停止;可以看到结果"Bag count is 300",如果用break,通知并行计算尽快的退出循环,可能结果是300多个或者300个 return; } bag.Add(i); }); stopWatch.Stop(); Console.WriteLine("Bag count is " + bag.Count + ", " + stopWatch.ElapsedMilliseconds); } //捕获异常 public void ParallelWithException() { stopWatch.Start(); try { Parallel.Invoke(Run1, Run2); } catch (AggregateException aex) { foreach (var ex in aex.InnerExceptions) { Console.WriteLine(ex.Message); } } stopWatch.Stop(); Console.WriteLine("Parallel run " + stopWatch.ElapsedMilliseconds + " ms."); stopWatch.Reset(); stopWatch.Start(); try { Run1(); } catch(Exception ex) { Console.WriteLine(ex.Message); } stopWatch.Stop(); Console.WriteLine("Normal run " + stopWatch.ElapsedMilliseconds + " ms."); } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Parallel学习 { class Program { static void Main(string[] args) { ParallelDemo pd = new ParallelDemo(); //pd.ParallelInvokeMethod(); //Console.ReadKey(); //pd.parallelForMethod(); //Console.ReadKey(); //pd.parallelForMethod2(); //Console.ReadKey(); //pd.parallelForeach(); //Console.ReadKey(); //pd.ParallelBreak(); //Console.ReadKey(); pd.ParallelWithException(); Console.ReadKey(); } } }