写在前面

之前微信公众号里有一位叫sara的朋友建议我写一下Parallel的相关内容,因为手中商城的重构工作量较大,一时之间无法抽出时间。近日,这套系统已有阶段性成果,所以准备写一下Parallel的相关内容,正好也延续之前的C#并发编程系列。

Parallel是并行编程的相关内容,而Parallel.For和Parallel.Foreach又是并行编程中相当重要的方法,所以不能孤立的去讨论Parallel,必须要放到并行编程的讨论中去

并行化,一般是对所要完成的任务进行划分,并且以并发的方式处理属于自己的那份任务,并且最终可以做到整合,所以并行化总会产生并发性。

实际上并行是并发的子集,并发和并行都可以是多线程执行,就看其处理器是否是多核的,就看这些线程能不能同时被cpu多个核执行,如果可以就说明是并行,而并发是多个线程被cpu单核轮流切换着执行。总之,只有在多核处理器上并行才会有意义

并行化总会有着很大的挑战,即每一个部分以不同顺序或者交错执行,都能保证最终结果的正确性,尤其涉及到各并行部分之间需要串行执行的部分,这个挑战是很大的。由于并行化程序设计要比普通的串行代码复杂很多,也难维护很多,所以不是所有的问题都可以使用并行的。比如绝对执行时间本来就很少,即使使用并发可以提高整体的执行时间,那么我们也应该使用传统方式。但是如果主要涉及到提升用户响应能力的功能,那么我们推荐使用并行编程,同时处理分割后依然可以独立进行而不影响整体任务的功能也可以使用并行编程。

并行的相关实战

说到并行,就需要先说下.NET FX4中引入的Task Parallel Library(任务并行库),简称TPL。TPL主要覆盖了三大使用场景,数据并行、任务并行和流水线,TPL以其高度的封装特性,隐藏了并行编程里复杂的处理,使得开发人员可以以较低的门槛进行并行编程。

数据并行

这种场景在于有大量数据需要处理,而且对每一份数据都要执行的同样的操作。

任务并行

有很多相对独立的不同操作,或者可以分割成多个子任务但彼此之间是独立的,可以通过任务并行来发挥并行化的优势

流水线

流水线是以上两种场景的结合,这个也是最复杂最难处理的场景,因为这里面涉及到多个并发的任务进行协调处理。

此场景,奈何小编理解的不是很好,所以不敢乱写,多方查找资料,找到了oschina上的一篇文章。

流水线技术,指的是允许一个机器周期内的计算机各处理步骤重叠进行。特别是,当执行一条指令时,可以读取下一条指令,也就意味着,在任何一个时刻可以有不止一条指令在“流水线”上,每条指令处在不同的执行阶段。这样,即便读取和执行每条指令的时间保持不变,而计算机的总的吞吐量提高了。

原文地址:https://my.oschina.net/u/3374461/blog/1930305

System.Threading.Tasks.Parallel类

虽然Parallel类在System.Threading.Tasks命名空间下,但是创建并行代码不一定要直接使用Task类的实例,事实上我们可以直接使用Parallel静态类所提供的方法。

Parallel.For:为固定数目的独立For循环迭代提供了负载均衡式的并行执行

   1:  Parallel.For(0, 5, i =>
   2:  {
   3:      Console.WriteLine("the number is", i);
   4:  });

Parallel.Foreach:为固定数目的独立ForEach循环迭代提供了负载均衡式的并行执行。这个方法支持自定义分区器(Partitioner),以使得我们截图完全掌控数据分发。

   1:  string[] letters = new string[] {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M"};
   2:  Parallel.ForEach(letters, i => Console.WriteLine("letter is " + i));

Parallel.Invoke:为给定的独立任务提供了负载均衡式的并行执行,接下来会重点讨论这个方法。

Parallel.Invoke

这个方法很实用,也很简单。

以下代码可以返回void的无参数方法:

   1:  Parallel.Invoke(Method1(), Method2(), Method3(), Method4());


通过Lambda表达式运行:

   1:  Parallel.Invoke(() => Method1(), () => Method2(), () => Method3(), () => Method4());


通过Lambda表达式和匿名类型来运行:

   1:  Parallel.Invoke(() =>
   2:  {
   3:      Method1();
   4:      // Do something
   5:  }, 
   6:  () =>
   7:  {
   8:      Method2();
   9:      // Do something
  10:  }, 
  11:  () =>
  12:  {
  13:      Method3();
  14:      // Do something
  15:  }, 
  16:  () =>
  17:  {
  18:      Method4();
  19:      // Do something
  20:  });


以上代码需要并行执行四个方法,但是如果空余逻辑内核不足四个或者根本就没有四个逻辑内核,这四个方法是不能并发执行的。因此在理想情况下,正好有至少四个空余逻辑内核时,我们就可以并行执行这四个方法了。

这四个方法,我们无法准确的预测其执行顺序,因为这一切是由底层的逻辑会根据运行时的现有可用资源创建出最合适的执行计划。当然TPL依然有机制保证方法的顺序执行,这个以后我们再讨论。

Parallel.Invoke最大的优势就是简单,但是并不能因为它简单,就不分场合的使用,事实上,我们需要在某些场景下权衡使用。

  • 如果这四个方法的执行时间不一致,那么就需要根据最长的执行时间才能返回控制,这就可能造成一些逻辑内核处于闲置状态。所以我们需要预测一下大致的执行时间,如果时间过长,那么就要认真考虑是否真的需要使用这个方法。
  • 其扩展性很差,因为它只能调用固定数目的逻辑内核,剩余内核就会一直处于闲置状态。
  • 方法之间的交互极其困难,极易产生Bug,当然这是并行编程的常见问题,TPL也考虑到了这点,也有足够机制解决这个问题。
  • 如果其中某个方法有了异常,捕捉异常会很困难,所以需要大家在相应的被调用方法里编写足够的日志。
  • 小编在以前的使用中还遇到了内存溢出的异常,这些也会在以后的文章中说明其原因以及解决方法。

今天就写到这儿吧,已经十二点了,要休息一下,保护头发了,哈哈哈。

C#并发编程之初识并行编程的更多相关文章

  1. 五 浅谈CPU 并行编程和 GPU 并行编程的区别

    前言 CPU 的并行编程技术,也是高性能计算中的热点,也是今后要努力学习的方向.那么它和 GPU 并行编程有何区别呢? 本文将做出详细的对比,分析各自的特点,为将来深入学习 CPU 并行编程技术打下铺 ...

  2. 第五篇:浅谈CPU 并行编程和 GPU 并行编程的区别

    前言 CPU 的并行编程技术,也是高性能计算中的热点,也是今后要努力学习的方向.那么它和 GPU 并行编程有何区别呢? 本文将做出详细的对比,分析各自的特点,为将来深入学习 CPU 并行编程技术打下铺 ...

  3. C#并行编程-并发集合

    菜鸟学习并行编程,参考<C#并行编程高级教程.PDF>,如有错误,欢迎指正. 目录 C#并行编程-相关概念 C#并行编程-Parallel C#并行编程-Task C#并行编程-并发集合 ...

  4. C#并行编程系列-文章导航

    菜鸟初步学习,不对的地方请大神指教,参考<C#并行编程高级教程.pdf> 目录 C#并行编程-相关概念 C#并行编程-Parallel C#并行编程-Task C#并行编程-并发集合 C# ...

  5. C#并行编程-相关概念

    菜鸟初步学习,不对的地方请大神指教,参考<C#并行编程高级教程.pdf> 目录 C#并行编程-相关概念 C#并行编程-Parallel C#并行编程-Task C#并行编程-并发集合 C# ...

  6. C#并行编程-Parallel

    菜鸟学习并行编程,参考<C#并行编程高级教程.PDF>,如有错误,欢迎指正. 目录 C#并行编程-相关概念 C#并行编程-Parallel C#并行编程-Task C#并行编程-并发集合 ...

  7. C#并行编程-Task

    菜鸟学习并行编程,参考<C#并行编程高级教程.PDF>,如有错误,欢迎指正. 目录 C#并行编程-相关概念 C#并行编程-Parallel C#并行编程-Task C#并行编程-并发集合 ...

  8. C#并行编程-线程同步原语

    菜鸟学习并行编程,参考<C#并行编程高级教程.PDF>,如有错误,欢迎指正. 目录 C#并行编程-相关概念 C#并行编程-Parallel C#并行编程-Task C#并行编程-并发集合 ...

  9. C#并行编程-PLINQ:声明式数据并行

    目录 C#并行编程-相关概念 C#并行编程-Parallel C#并行编程-Task C#并行编程-并发集合 C#并行编程-线程同步原语 C#并行编程-PLINQ:声明式数据并行 背景 通过LINQ可 ...

随机推荐

  1. Linux c++ vim环境搭建系列(5)——vim使用

    5. 使用 5.1 快捷键及设置 5.1.1 光标移动 w : 正向移动到相邻单词的首字符 b : 逆向移动到相邻单词的首字符 e : 正向移动到相邻单词的尾字符 ge : 逆向移动到相邻单词的尾字符 ...

  2. SpringBoot项目中容易出现的问题

    SpringBoot项目的配置文件 另外启动文件的位置一定要在其它类的顶层,SpringBoot所在的main函数的同级包或子包在生效 开始做这个的时候最容易把配置文件搞错,造成sql查询异常

  3. Salesforce Spring '20新功能集锦系列(二)

    一.使用Data Mask保护沙盒数据 对于Salesforce管理员和开发人员,Data Mask是功能强大的新数据安全资源.管理员可以使用数据掩码自动加密沙盒中的数据,无需手动保护数据和沙盒组织的 ...

  4. SpringBoot连接Redis服务出现DENIED Redis is running in protected mode because protected mode is enabled

    修改redis.conf,yes 改为 no

  5. API联调神器PostMan使用详解

    简介 创建 + 测试:创建和发送任何的HTTP请求,请求可以保存到历史中再次执行 Organize:使用Postman Collections为更有效的测试及集成工作流管理和组织APIs docume ...

  6. 2020.4面试分享(7面收5个offer)

    都说金三银四是找工作的最佳时节,由于本人的个人职业规划跟目前工作内容不太相符(具体原因就不透露了,领导平时也要来这里逛,哈哈),四月份挑选了10多家公司投递简历(公司规模从几十人到上万人都有),参加了 ...

  7. selenium 元素定位常用的方法

    元素定位的方法有2个 driver.findElement(By.args) 返回值是WebElement            //此方法是获取单一的页面元素 driver.findElements ...

  8. Springboot:员工管理之查询员工列表(十(6))

    构建员工controller com\springboot\controller\EmployeeController.java package com.springboot.controller; ...

  9. tp3.2 事务 和 tp5.0事务

    tp3.2: 来源:https://www.kancloud.cn/thinkphp-development/tp323/423369 和: https://blog.csdn.net/mengzuc ...

  10. phpcms 用phpexcel导入导出excel

    html <form method="post" action="?m=content&c=content&a=public_add_excel&q ...