欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

并行开发基础

程序员文章站 2022-12-25 08:05:05
并行开发适合用于分解计算密集型的任务片段,并将它们分配给多个线程。 1、数据的并行处理 有一批数据,需要对每个元素进行相同的操作。该操作是计算密集型,需要耗费一定的时间。Parallel类型的 ForEach 方法就是专门为此设计的。 Parallel的ForEach可以对一系列值进行并行处理。还有 ......

  并行开发适合用于分解计算密集型的任务片段,并将它们分配给多个线程。

 1、数据的并行处理

   有一批数据,需要对每个元素进行相同的操作。该操作是计算密集型,需要耗费一定的时间。Parallel类型的 ForEach 方法就是专门为此设计的。

Parallel的ForEach可以对一系列值进行并行处理。还有类似的解决方案,就是PLINQ(并行LINQ)。

Parallel和PLINQ的区别:PLINQ假设可以使用计算机的所以CPU核,而Parallel会根据CPU的状态进行动态调整。

Parallel的ForEach是并行版本的foreach版本。Parallel类也提供了并行版本的for循环Parallel.For。如果有多个数组的数据,并且采用了相同的索引,Parallel.For方法就比较适合。

 

2、并行聚合

  在并行操作结束时,需要集合结果,包括累加和、平均值等。

  在Parallel中可以使用加锁的方法,来进行聚合。 

  PLINQ中聚合的支持,比Parallel类使用更顺手。

  

    private static int ParallelSum(IEnumerable<int> values)
        {
            return values.AsParallel<int>().Sum();
        }

 

3、并行调用

  需要并行调用一批方法,并且这些方法(大部分)是互相独立的。 Parallel.Invoke方法就是用于这种场合。

  例如并行调用一个方法10次:

    private static void DoAction10Count(Action action)
        {
            Action[] actions = Enumerable.Repeat(action, 10).ToArray();
            Parallel.Invoke(actions);
        }

对于简单的并行调用, Parallel.Invoke是一个不错的方式。但是,对于每一个输入都要调用一个操作,改用Parallel.Foreach,或者每一个操作要产生一个输出,改用PLINQ可能更好。

 

4、动态并行

  并行任务的结构和数量要在运行时才能确定,这是一种更复杂的并行编程。

  任务并行库(TPL)是以Task类为中心构建的。Parallel和PLINQ都是为了使用方便,对Task类的封装。

  实现动态并行最简单的做法就是直接使用 Task 类。

  

  在并行中是用Task和在异步中使用Task完全不同:

    并行:并行任务可以使用阻塞的成员函数。例如:Task.WaitAll,Task.Wait,Taks.Result,Taks.WaitAny。并行任务通常也使用AttachedToParent来建立任务之间的父/子关系。

       并行任务的创建需要使用Task.Run或者Task.Factory.StartNew方法。

    

    异步:异步任务应该避免使用阻塞的成员函数。而应该使用await,Task.WhenAll、Taks.WhenAny。

 

5、并行LINQ

  需要对一批数据进行处理,生成另外一批数据,或者对数据进行统计。

  PLINQ为各种操作提供了并行操作,包括过滤、投影、聚合等。

  PLINQ适合于对数据流进行操作,一个数据队列做为输入,一个数据队列做为输出。