俏江南菜单,出租车驾驶员贷款,包皮环切价格
有一批数据,需要对每个元素进行相同的操作。该操作是计算密集型的,需要耗费一定的时间。
常见的操作可以粗略分为 计算密集型操作 和 io密集型操作。计算密集型操作主要是依赖于cpu计算,所以可以最大限度利用多核cpu的并行操作非常适合计算密集型操作。图像操作是比较常见的计算密集型操作,图像操作一般是借助矩阵存储图像数据,该书作者就举了矩阵旋转为例。
思路是借助parallel.foreach实现并行操作。
伪代码如下
void rotatematrices(ienumerable<matrix> matrices, float degrees) { parallel.foreach(matrices, matrix => matrix.rotate(degrees)); }
当前循环处理无效值时,可能需要停止该循环,实现如下
void invertmatrices(ienumerable<matrix> matrices) { parallel.foreach(matrices, (matrix, state) => { if (!matrix.isinvertible) state.stop(); else matrix.invert(); }); }
而如果是想要取消整个并行循环,则需要借助cancellationtoken,即可以有一个取消按钮,点击取消按钮,应取消循环操作。
void rotatematrices(ienumerable<matrix> matrices, float degrees, cancellationtoken token) { parallel.foreach(matrices, new paralleloptions { cancellationtoken = token }, matrix => matrix.rotate(degrees)); }
另:当一个全局变量在并行循环内部被操作时,则需要考虑多进程共享状态。因为并行循环的每个循环很可能在不同的线程中运行。
// 注意,这不是最高效的实现方式。 // 只是举个例子,说明用锁来保护共享状态。 int invertmatrices(ienumerable<matrix> matrices) { object mutex = new object(); int noninvertiblecount = 0; parallel.foreach(matrices, matrix => { if (matrix.isinvertible) { matrix.invert(); } else { lock (mutex) { ++noninvertiblecount; } } }); return noninvertiblecount; }
在 《c#并发编程经典实例》学习笔记-第一章并发编程概述 - repeatedly - 博客园 ,我提到了并行操作的两种方式,一种是parallel,另一种是plinq(parallel linq)。所以上述操作也可以使用plinq实现。
两者是有区别的,区别如下:
parallel 类和 plinq 之间有一个区别:plinq 假设可以使用计算机内所有的cpu 核,而 parallel 类则会根据 cpu 状态的变化动态地调整。
相信对c#语法比较熟悉的应该能看出来,parallel.foreach是并行foreach循环,那么并行for循环对应的方法是什么呢?是parallel.for 方法。
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
Blazor server side 自家的一些开源的, 实用型项目的进度之 CEF客户端
.NET IoC模式依赖反转(DIP)、控制反转(Ioc)、依赖注入(DI)
vue+.netcore可支持业务代码扩展的开发框架 VOL.Vue 2.0版本发布
网友评论