zoukankan      html  css  js  c++  java
  • 【c#基础】并行Linq

    并行:指在同一时刻,有多条指令在多个处理器上同时执行

    并发:指在同一时刻只能有一条指令执行,但多个进程指令被快速的轮换执行,使得在宏观上具有多个进程同时执行的效果,但在微观上并不是同时执行的,只是把时间分成若干段,使多个进程快速交替的执行

    并发是逻辑上的同时发生(simultaneous),而并行是物理上的同时发生。 

    串行:A和B两个任务运行在一个CPU线程上,在A任务执行完之前不可以执行B。即,在整个程序的运行过程中,仅存在一个运行上下文,即一个调用栈一个堆。程序会按顺序执行每个指令。

    1:并行Linq

    System.Linq名称空间包含的类ParallelEnumerable可以分解查询的工作,使其分布在多个线程上。

    尽管Enumerable类给IEnumerable<T>接口定义了扩展方法。但ParallelEnumerable类的大多数扩展方法是ParallelQuery<TSource>类的扩展。AsParallel()方法,它扩展了IEnumerable<TSource>接口,返回ParallelQuery<TSource>类,所以正常的集合类可以以并行方式查询。

    2:并行查询

     对于可以放在CPU缓存中的小集合,并行Linq看不出效果。

    AsParallel()方法用ParallelEnumerable()类定义,以扩展IEnumerable<T>接口,所以可以对简单的数组调用它,AsParallel()方法返回ParallelQuery<TSource>。因为返回的类型,所以编译器选择的Where()方法是ParallelEnumerable.Where()。与Enumerable类的实现代码相反,对于ParallelEnumerable类,查询时分区的,以便多个线程可以同时处理该查询。

    集合可以分为多个部分,其中每个部分由不同的线程处理,以赛选其选项。,完成分区工作后,需要合并,获得所有部分的总和

    1  static IEnumerable<int> SampleData()
    2         {
    3             const int arraySize = 50000000;
    4             var r = new Random();
    5             return Enumerable.Range(0, arraySize).Select(x => r.Next(140)).ToList();
    6         }
     static void Main(string[] args)
            {
                var data = SampleData();
                var res = data.AsParallel().Where(x => Math.Log(x) < 4).Select(x => x).Average();
                Console.WriteLine(res);
               
            }

    data.AsParallel()这行代码从任务管理器,中可以看出系统的所有CPU利用率上升,使用多个cpu在运行,如果系统上没有多个cpu,就不会看到并行版本带来的改进。

    下图为使用AsParaller()后的cpu使用率和所有处理器的百分比 12行代码使用率为13.04%左右

     未使用AsParallel()

     从上面两张截图可以看出 使用了AsParallel()的CPU的百分比是比未使用AsParallel()的百分比高的,但是cpu的使用率则是相反的。使用了AsParallel()的使用率会比没使用的会更低。

    电脑配置说明:运行该例子的是双核cpu。

    3:分区器

    AsParallel()方法不仅扩展了IEnumerable<T>接口,还扩展了Partitioner类,通过它,可以影响要创建的分区。

    Partitioner类用System.Collection.Concurrent名称空间定义,并且有不同的变体。

    Create()方法接受实现了IList<T>类的数组或对象。根据这一点,以及Boolean类型的参数loadBalance和该方法的一些重载版本,会返回一个不同的Partitioner类型。对于数组,使用派生基类OrderablePartitioner<TSource>的DynamicPartitionerForArray<TSource>类和StaticPartitionerForArray<TSource>类。

    1  var result =
    2                 (from x in Partitioner.Create(data.ToList(), true).AsParallel() where Math.Log(x) < 4 select x).Average();
    3             Console.WriteLine(result);

    也可以调用WithExecutionMode()和WithDegreeOfParallelism()方法,来影响并行机制。

    对于WithExecutionMode()方法可以传递ParallelExecutionMode的一个Default值或者ForceParallelism值。 默认情况下,并行Linq避免使用系统开销很高的并行机制。

    对于WithDegreeOfParallelism()方法可以传递一个整数值,以指定应并行运行的最大任务数。

    查询不应使用全部CPU,这个方法会很有用

    4:取消

    .Net提供乐乐一种标准方式,来取消长时间运行的任务,这也适用于并行Linq。

    要取消长时间运行的查询,可以给查询添加WithCancellation()方法,并传递一个CancellationToken令牌作为参数。

    CancellationToken令牌从CancellationTokenSource类中创建。该查询在单独的线程中运行。

    在该线程中,捕获一个OperationCanceledException类型异常。如果取消了查询。就触发这个异常,在主线程中,调用CancellationTokenSource类的Cancel()方案可以取消任务。

     1    var cts = new CancellationTokenSource();
     2             Task.Run(() => {
     3                 try
     4                 {
     5                     var res = (from x in data.AsParallel().WithCancellation(cts.Token) where Math.Log(x) < 4 select x)
     6                         .Average();
     7                     Console.WriteLine($"query finished,sum:{res}");
     8                 }
     9                 catch (Exception e)
    10                 {
    11                     Console.WriteLine(e.Message);
    12                 }}, cts.Token);
    13             Console.WriteLine("query start");
    14             Console.Write("Cancel?");
    15             string input = Console.ReadLine();
    16             if (input != null && input.ToLower().Equals("y"))
    17             {
    18                 cts.Cancel();
    19             }
  • 相关阅读:
    3dsmax script export/import tools
    BOBO输出插件的一些信息
    任务
    说说谷歌在线电子表格
    EditGrid在线编辑Excel文档
    如何控制,textField的宽度,
    在线文档管理平台
    雅虎的这个效果,有机会实现一下
    推荐在线电子表格EditGrid
    我的台账录入界面
  • 原文地址:https://www.cnblogs.com/SignX/p/11495117.html
Copyright © 2011-2022 走看看