C#并发编程之初识并行编程
写在前面
之前微信公众号里有一位叫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#并发编程之初识并行编程的更多相关文章
- 五 浅谈CPU 并行编程和 GPU 并行编程的区别
前言 CPU 的并行编程技术,也是高性能计算中的热点,也是今后要努力学习的方向.那么它和 GPU 并行编程有何区别呢? 本文将做出详细的对比,分析各自的特点,为将来深入学习 CPU 并行编程技术打下铺 ...
- 第五篇:浅谈CPU 并行编程和 GPU 并行编程的区别
前言 CPU 的并行编程技术,也是高性能计算中的热点,也是今后要努力学习的方向.那么它和 GPU 并行编程有何区别呢? 本文将做出详细的对比,分析各自的特点,为将来深入学习 CPU 并行编程技术打下铺 ...
- C#并行编程-并发集合
菜鸟学习并行编程,参考<C#并行编程高级教程.PDF>,如有错误,欢迎指正. 目录 C#并行编程-相关概念 C#并行编程-Parallel C#并行编程-Task C#并行编程-并发集合 ...
- C#并行编程系列-文章导航
菜鸟初步学习,不对的地方请大神指教,参考<C#并行编程高级教程.pdf> 目录 C#并行编程-相关概念 C#并行编程-Parallel C#并行编程-Task C#并行编程-并发集合 C# ...
- C#并行编程-相关概念
菜鸟初步学习,不对的地方请大神指教,参考<C#并行编程高级教程.pdf> 目录 C#并行编程-相关概念 C#并行编程-Parallel C#并行编程-Task C#并行编程-并发集合 C# ...
- C#并行编程-Parallel
菜鸟学习并行编程,参考<C#并行编程高级教程.PDF>,如有错误,欢迎指正. 目录 C#并行编程-相关概念 C#并行编程-Parallel C#并行编程-Task C#并行编程-并发集合 ...
- C#并行编程-Task
菜鸟学习并行编程,参考<C#并行编程高级教程.PDF>,如有错误,欢迎指正. 目录 C#并行编程-相关概念 C#并行编程-Parallel C#并行编程-Task C#并行编程-并发集合 ...
- C#并行编程-线程同步原语
菜鸟学习并行编程,参考<C#并行编程高级教程.PDF>,如有错误,欢迎指正. 目录 C#并行编程-相关概念 C#并行编程-Parallel C#并行编程-Task C#并行编程-并发集合 ...
- C#并行编程-PLINQ:声明式数据并行
目录 C#并行编程-相关概念 C#并行编程-Parallel C#并行编程-Task C#并行编程-并发集合 C#并行编程-线程同步原语 C#并行编程-PLINQ:声明式数据并行 背景 通过LINQ可 ...
随机推荐
- 自己总结 :并发队列ConcurrentLinkedQueue、阻塞队列AraayBlockingQueue、阻塞队列LinkedBlockingQueue 区别 和 使用场景总结
并发队列ConcurrentLinkedQueue.阻塞队列AraayBlockingQueue.阻塞队列LinkedBlockingQueue 区别 和 使用场景总结 分类: Java2013-0 ...
- lambda表达式,及lambda简化过程
lambda表达式(jdk8特性) 1.为什么要用lambda表达式 原因:因为我们有时候需要用到很多类,但是,这些类我们只用一次或者两次,所以我们用匿名内部类,但是匿名内部类多了还是很麻烦,所以用l ...
- Equalizing by Division
The only difference between easy and hard versions is the number of elements in the array. You are g ...
- JavaScript中的作用域和作用域链(边学边写)[看着别人的博客纯手敲]
作用域是JavaScript最重要的概念之一,想要学好JavaScript就需要理解JavaScript作用域和作用域的工作原理.今天这篇文章对JavaScript作用域和作用域链简单的介绍,希望能帮 ...
- linux常用命令--文件和目录
cd /home 进入 '/ home' 目录' cd .. 返回上一级目录 cd ../.. 返回上两级目录 cd 进入个人的主目录 cd ~user1 进入个人的主目录 cd - 返回上次所在的目 ...
- 全球数字高程数据(DEM)详解,还有地形晕渲、等高线等干货
1 基本概念 DEM是数字高程模型的英文简称(Digital Elevation Model),是研究分析地形.流域.地物识别的重要原始资料.由于DEM 数据能够反映一定分辨率的局部地形特征,因此通过 ...
- tp5 auth权限的原理
我的一些个人理解,还是有些不懂的地方,有错误请指正,谢谢!!! class Auth{ //默认配置 protected $_config = array( 'auth_on' => true, ...
- 查看现有的 cipher suite
openssl ciphers [-v] [-ssl2] [-ssl3] [-tls1] [cipherlist]
- Spring5参考指南:AOP代理
文章目录 AOP代理 AOP Proxies原理 AOP代理 通常来说Spring AOP有两种代理方式,一种默认的JDK代理,只能代理接口,一种是CGLIB代理,可以代理具体的类对象. Spring ...
- 比特大陆发布终端 AI 芯片 端云联手聚焦安防
雷帝网 乐天 10月17日报道 比特大陆今日正式发布终端人工智能芯片BM1880,一同发布的还有基于云端人工智能芯片 BM1682 的算丰智能服务器 SA3.嵌入式AI迷你机 SE3.3D 人脸识别智 ...