【C#】并行编程实战:并行编程中的模式
本章将介绍并行编程模式,重点是理解并行代码问题场景并使用并行编程/异步技术解决他们。本章会介绍几种最重要的编程模式。
本教程学习工程:魔术师Dix / HandsOnParallelProgramming · GitCode
1、MapReduce 模式
引入 MapReduce 是为了解决处理大数据的问题,例如跨服务器的大规模计算需求。该模式可以在单核计算机上使用。
1.1、映射和归约
MapReduce 程序顾名思义,即 Map(映射) + Reduce(归约)。MapReduce 程序的输入作为键值对被传递,输出也是同样形式。
书上讲的听起来很抽象,画张图来辅助理解:
输入一个列表,然后通过某种方式先进行筛选(返回列表),然后进行分组(返回键值),最后返回各个分组的键值对作为结果:
1.2、使用 LINQ 实现 MapReduce
其示例中,扩展方法如下:
public static ParallelQuery<TResult> MapReduce<TSource, TMapped, TKey, TResult>(this ParallelQuery<TSource> source,Func<TSource, IEnumerable<TMapped>> map,Func<TMapped, TKey> keySelector,Func<IGrouping<TKey, TMapped>, IEnumerable<TResult>> reduce){return source.SelectMany(map).GroupBy(keySelector).SelectMany(reduce);}
我们用一个需求来理解这段函数:
-
源数据为 1000 个 -100~100 的随机数;
-
筛选出其中的正数;
-
将其按照10位进行分组(0~9一组、10~19一组,以此类推);
-
统计每个分组的个数。
那么,使用上述 MapReduce 模板进行处理,示例代码如下:
private void RunMapReduce(){//初始化原始数据int length = 1000;List<int> L = new List<int>(length);for (int i = 0; i < length; i++){L.Add(Random.Range(-100, 100));}var ret = L.AsParallel().MapReduce(mapPositiveNumbers,//筛选正数groupNumbers,//映射分组reduceNumbers);//归约合并结果foreach (var item in ret){Debug.Log($"{item.Key * 10} ~ {(item.Key + 1) * 10} 出现了:{item.Value} 次 !");}}public static IEnumerable<int> mapPositiveNumbers(int number){IList<int> PositiveNumbers = new List<int>();if (number > 0)PositiveNumbers.Add(number);return PositiveNumbers;}public static int groupNumbers(int number){return number / 10;}public static IEnumerable<KeyValuePair<int, int>> reduceNumbers(IGrouping<int, int> grouping){return new[]{new KeyValuePair<int, int>(grouping.Key,grouping.Count())};}
运行结果如下所示:
通过上述示例,这个映射与归约就容易理解多了:实际上就是某一种特定的业务模板写法:筛选 → 分组 → 合并。在并行编程中,类似这样的写法都可以通过同样的模板代码实现。
2、聚合
聚合(Aggregation)是并行应用程序中使用的另一种常见的设计模式。在并行程序中,数据被划分为多个单元,以便可以通过多个线程在内核之间进行处理。在某个时候,需要将所有相关来源数据组合起来,然后才能呈现给用户。
书上的例子只讨论了使用 PLINQ 代码的示例,我们也照着写一个:
private void RunAggregation(){var L = Utils.GetOrderList(10);var L2 = L.AsParallel().Select(TestFunction.IntToString)//并行处理.ToList();//合并foreach (var item in L2)Debug.Log(item);}public static string IntToString(int x){return $"ToString_{x}";}
上述代码运行结果如下:
可以看到,这个运行模式是保证顺序的(源数据是List)。
一般来讲,我们为了避免锁、同步等额外处理,要么使用 PLINQ 这样的语法,要么使用并发集合。这样可以减少我们需要手动处理锁、同步等工作。
3、分叉/合并模式
在分叉/合并(Fork/Join)模式中,工作被分叉(拆分)为一组可以异步执行的任务,然后根据并行化的要求和范围,以相同(或不同)的顺序合并分叉的任务。
分叉/合并模式常见的一些实现如下:
-
Parallel.For
-
Parallel.ForEach
-
Paralle.Invoke
-
System.Threading.CountdownEvent
利用这些同步框架开发人员能快速实现开发,而不必担心同步开销(系统已经内部处理同步了,实际上如如果额外开销不可接受,用这些 API 也没办法优化)。
我们将之前的代码通过 分叉/合并模式 再改一版:
private void RunForkJoin(){var L = Utils.GetOrderList(10);ConcurrentQueue<string> queue = new ConcurrentQueue<string>();Parallel.For(0, L.Count, x =>{var ret = IntToString(x);queue.Enqueue(ret);});while (queue.Count > 0){string str;if (queue.TryDequeue(out str))Debug.Log(str);}}
这次我们看运行结果:
很显然,已经乱序了,这种模式就没有按照原来数据顺序进行数据处理。这也是这个模式的特点之一,我们可以选择是否要按照顺序进行合并。
4、推测处理模式
推测处理模式(Speculative Processing Pattern)是依赖高吞吐量以减少等待时间的另一种并行编程模式。
推测处理模式(Speculative Processing Pattern):
如果同时存在多种处理任务,但并不知道哪一种方式速度最快。因此第一个执行的完成的任务将被输出,其他任务处理结果将会忽略。
以下是一种推测处理模式的常见写法:
//选择一个最快执行方法的结果并返回public static TResut SpeculativeForEach<TSource, TResut>(TSource source, IEnumerable<Func<TSource, TResut>> funcs){TResut result = default;Parallel.ForEach(funcs, (func, loopState) =>{result = func(source);loopState.Stop();});return result;}//返回特定方法的最快执行结果并返回public static TResut SpeculativeForEach<TSource, TResut>(IEnumerable<TSource> source, Func<TSource, TResut> func){TResut result = default;Parallel.ForEach(source, (item, loopState) =>{result = func(item);loopState.Stop();});return result;}
这种写法只会返回一个结果,首先完成的任务将被返回。但是其他任务仍然有可能执行完成,只是结果将不会被返回。
这里我们选择方法一进行示例,调用代码如下:
private void RunSpeculativeMethod_1(){Debug.Log($">===== RunSpeculativeMethod_1 开始 =====<");var L1 = new List<Func<int, string>>{IntToString,IntToString2};string result = SpeculativeForEach(4, L1);Debug.Log($"运行结果:{result}");}
连续运行2次,其结果如下:
第一次是使用了 IntToString2 的结果,而第二次使用的 IntToString 的结果。
5、延迟模式
也就是在使用时才创建,也就是懒加载。这个在之前的章节中已经有详细介绍了,这里就不重复了。
详见:使用延迟初始化提高性能
【C#】并行编程实战:使用延迟初始化提高性能_魔术师Dix的博客-CSDN博客在前面的章节中讨论了 C# 中线程安全并发集合,有助于提高代码性能、降低同步开销。本章将讨论更多有助于提高性能的概念,包括使用自定义实现的内置构造。本章主要内容为通过延迟初始化提高性能,相对比较简单。https://blog.csdn.net/cyf649669121/article/details/131780600
6、共享状态模式
这个主要在 【C#】并行编程实战:同步原语(1)_魔术师Dix的博客-CSDN博客 中已经介绍过共享状态(Shared State Pattern)的实现(其实就是各种加锁,搞的好像很高级)。
不过上锁不能上太多,不然性能很差;而且我们也应该尽可能实现无锁代码。
7、本章小结
本章介绍了各种并行编程模式,其实就是各种模板的示例。当然,这里讲的不可能包罗所有,只是给大家提供一些参考。至此,多线程编程的学习告一段落,书上的内容已经讲完了。后续如果有补充会加到这个系列里。
多线程的实践还是需要在项目中多多练习。
本教程学习工程:魔术师Dix / HandsOnParallelProgramming · GitCode
相关文章:
【C#】并行编程实战:并行编程中的模式
本章将介绍并行编程模式,重点是理解并行代码问题场景并使用并行编程/异步技术解决他们。本章会介绍几种最重要的编程模式。 本教程学习工程:魔术师Dix / HandsOnParallelProgramming GitCode 1、MapReduce 模式 引入 MapReduce 是为了解决处理大数据的问…...
![](https://www.ngui.cc/images/no-images.jpg)
Apache Kafka 入门教程
Apache Kafka 入门教程 一、简介简介架构 二、Kafka 安装和配置JDK安装 Kafka配置文件详解 三、Kafka 的基本操作启动和关闭Topic 创建和删除Partitions 和 Replication 配置Producer 和 Consumer 使用方法ProducerConsumer 四、Kafka 高级应用消息的可靠性保证Kafka StreamKaf…...
![](https://img-blog.csdnimg.cn/img_convert/ec2e9b44f21100ea91ea7e48e7e51a07.jpeg)
python皮卡丘编程代码教程,用python打印皮卡丘
大家好,小编来为大家解答以下问题,如何用print函数打印一只皮卡丘,用python如何打印丘比特之心,现在让我们一起来看看吧!...
![](https://img-blog.csdnimg.cn/4c39daaac4e44a36985054b5532f00cb.png)
shell脚本:数据库的分库分表
#!/bin/bash ######################### #File name:db_fen.sh #Version:v1.0 #Email:admintest.com #Created time:2023-07-29 09:18:52 #Description: ########################## MySQL连接信息 db_user"root" db_password"RedHat123" db_cmd"-u${…...
![](https://www.ngui.cc/images/no-images.jpg)
AtCoder Beginner Contest 312(A~D)
A //语法题也要更仔细嘞,要不然也会wa #include <bits/stdc.h> // #pragma GCC optimize(3,"Ofast","inline") // #pragma GCC optimize(2) using namespace std; typedef long long LL; #define int LL typedef pair<int, int> …...
![](https://www.ngui.cc/images/no-images.jpg)
SQL中Partition的相关用法
使用Partition可以根据指定的列或表达式将数据分成多个分区。每个分区都是逻辑上独立的,可以单独进行查询、插入、更新和删除操作。Partition可以提高查询性能,因为它可以限制在特定分区上执行查询,而不是在整个表上执行。 在SQL中ÿ…...
![](https://img-blog.csdnimg.cn/f9b61e08c48b4d37a5fbf60c223d37db.png)
微服务——Docker
docker与虚拟机的区别 首先要知道三个层次 硬件层:计算机硬件 内核层:与硬件交互,提供操作硬件的指令 应用层: 系统应用封装内核指令为函数,便于程序员调用。用户程序基于系统函数库实现功能。 docker在打包的时候直接把应用层的函数库也进行打包&a…...
![](https://img-blog.csdnimg.cn/1e0b1a9ef07145b88efcab5987fe4529.png)
测试|测试用例方法篇
测试|测试用例方法篇 文章目录 测试|测试用例方法篇1.测试用例的基本要素:测试环境,操作步骤,测试数据,预期结果…2.测试用例带来的好处3.测试用例的设计思路,设计方法,具体设计方法之间的关系**设计测试用…...
![](https://www.ngui.cc/images/no-images.jpg)
负载均衡的策略有哪些? 负载均衡的三种方式?
负载均衡的策略有哪些? 负载均衡的策略有如下: 1. 轮询(Round Robin):按照请求的顺序轮流分配到不同的服务器。 2. 权重(Weighted):给不同的服务器分配不同的权重,根据权重比例来…...
![](https://img-blog.csdnimg.cn/ccd6d5b34caf4ead95b6e858d310a4f7.png)
二十三章:抗对抗性操纵的弱监督和半监督语义分割的属性解释
0.摘要 弱监督语义分割从分类器中生成像素级定位,但往往会限制其关注目标对象的一个小的区域。AdvCAM是一种图像的属性图,通过增加分类分数来进行操作。这种操作以反对抗的方式实现,沿着像素梯度的相反方向扰动图像。它迫使最初被认为不具有区…...
![](https://www.ngui.cc/images/no-images.jpg)
curator实现的zookeeper可重入锁
Curator是一个Apache开源的ZooKeeper客户端库,它提供了许多高级特性和工具类,用于简化在分布式环境中使用ZooKeeper的开发。其中之一就是可重入锁。 Curator提供了InterProcessMutex类来实现可重入锁。以下是使用Curator实现ZooKeeper可重入锁的示例&am…...
![](https://img-blog.csdnimg.cn/0e8ed9de41234cf6b41bf8cd986aeb22.png)
抽象工厂模式——产品族的创建
1、简介 1.1、简介 抽象工厂模式为创建一组对象提供了一种解决方案。与工厂方法模式相比,抽象工厂模式中的具体工厂不只是创建一种产品,它负责创建一族产品 1.2、定义 抽象工厂模式(Abstract Factory Pattern):提供…...
![](https://img-blog.csdnimg.cn/2fa02dff54c24f75a68f419c86cf25b5.png#pic_center)
【C语言初阶篇】自定义类型结构体我不允许还有人不会!
🎬 鸽芷咕:个人主页 🔥 个人专栏:《C语言初阶篇》 《C语言进阶篇》 ⛺️生活的理想,就是为了理想的生活! 文章目录 📋 前言1 . 什么是结构体1.1 结构的定义1.2 结构的声明 2.结构体初始化2.1 用标签名定义和初始化2.2…...
![](https://img-blog.csdnimg.cn/29b8a24fd60645dbabdded646166cd9a.jpeg)
重大更新|Sui主网即将上线流动性质押,助力资产再流通
Sui社区一直提议官方上线流动质押功能,现在通过SIP过程,已经升级该协议以实现这一功能。 Sui使用委托权益证明机制(DPoS)来选择和奖励负责运营网络的验证节点。为了保障网络安全,验证节点通过质押SUI token获得质押奖…...
![](https://www.ngui.cc/images/no-images.jpg)
day3 驱动开发 c语言编程
通过ioctl(内核应用层) 控制led灯三盏,风扇,蜂鸣器,小马达 头文件head.h #ifndef __LED_H__ #define __LED_H__typedef struct {volatile unsigned int TZCR; // 0x000volatile unsigned int res1[2]; // 0x…...
![](https://img-blog.csdnimg.cn/9b0df72add7842fe97be4139aa2afd9a.png)
【字节跳动青训营】后端笔记整理-3 | Go语言工程实践之测试
**本文由博主本人整理自第六届字节跳动青训营(后端组),首发于稀土掘金:🔗Go语言工程实践之测试 | 青训营 目录 一、概述 1、回归测试 2、集成测试 3、单元测试 二、单元测试 1、流程 2、规则 3、单元测试的例…...
![](https://www.ngui.cc/images/no-images.jpg)
【Android】Recyclerview的缓存复用
介绍 RecyclerView是Android开发中常用的一个高度可定制的列表视图组件。它是在ListView和GridView的基础上进行了改进和增强,旨在提供更好的性能和更灵活的布局管理。 RecyclerView的主要特点如下: 灵活的布局管理器(LayoutManager&#…...
![](https://img-blog.csdnimg.cn/7c55946709514686886c7d3ab2377ee3.png)
机器学习:混合高斯聚类GMM(求聚类标签)+PCA降维(3维降2维)习题
使用混合高斯模型 GMM,计算如下数据点的聚类过程: Datanp.array([1,2,6,7]) 均值初值为: μ1,μ21,5 权重初值为: w1,w20.5,0.5 方差: std1,std21,1 K2 10 次迭代后数据的聚类标签是多少? 采用python代码实现: from scipy import…...
![](https://www.ngui.cc/images/no-images.jpg)
libuv库学习笔记-processes
Processes libuv提供了相当多的子进程管理函数,并且是跨平台的,还允许使用stream,或者说pipe完成进程间通信。 在UNIX中有一个共识,就是进程只做一件事,并把它做好。因此,进程通常通过创建子进程来完成不…...
![](https://img-blog.csdnimg.cn/eb58f6b6652e472780284cc4e59998c7.png#pic_center)
c++ 给无名形参提供默认值
如上图,若函数的形参不在函数体里使用,可以不提供形参名,而且可以给此形参提供默认值。也能编译通过。 在看vs2019上的源码时,也出现了这种写法。应用SFINAE(substitute false is not an error)原则&#x…...
![](https://img-blog.csdnimg.cn/567d3f479a9f45c3a0a0dfcd04baa073.png)
NO1.使用命令行创建Maven工程
①在工作空间目录下打开命令窗口 ②使用命令行生成Maven工程 mvn archetype:generate 运行 MVN 原型:生成命令,下面根据提示操作 选择一个数字或应用过滤器(格式:[groupId:]artifactId,区分大小写包含)&a…...
![](https://img-blog.csdnimg.cn/f675b9a173fa477b9ff3e1e5f6de8638.png#pic_center)
深度学习入门(一):神经网络基础
一、深度学习概念 1、定义 通过训练多层网络结构对位置数据进行分类或回归,深度学习解决特征工程问题。 2、深度学习应用 图像处理语言识别自然语言处理 在移动端不太好,计算量太大了,速度可能会慢 eg.医学应用、自动上色 3、例子 使用…...
![](https://img-blog.csdnimg.cn/d915e13a0e8a4f7a8a54a2a779ee0329.png)
网络知识整理
网络知识整理 网络拓扑网关默认网关 数据传输拓扑结构层面协议层面 网络拓扑 网关 连接两个不同的网络的设备都可以叫网关设备,网关的作用就是实现两个网络之间进行通讯与控制。 网关设备可以是交换机(三层及以上才能跨网络) 、路由器、启用了路由协议的服务器、代…...
![](https://img-blog.csdnimg.cn/img_convert/44408a5e523a1d0369ae7fae1ab2a058.png)
如何有效地使用ChatGPT写小说讲故事?
构思故事情节,虽有趣但耗时,容易陷入写作瓶颈。ChatGPT可提供灵感,帮你解决写作难题。要写出引人入胜的故事,关键在于抓住八个要素——主题、人物、视角、背景、情节、语气、冲突和解决办法。 直接给出故事模板,你可…...
![](https://img-blog.csdnimg.cn/111dce1a8f8348789de0879e8c1dcd84.png)
原生求生记:揭秘UniApp的原生能力限制
文章目录 1. 样式适配问题2. 性能问题3. 原生能力限制4. 插件兼容性问题5. 第三方组件库兼容性问题6. 全局变量污染7. 调试和定位问题8. 版本兼容性问题9. 前端生态限制10. 文档和支持附录:「简历必备」前后端实战项目(推荐:⭐️⭐️⭐️⭐️…...
![](https://img-blog.csdnimg.cn/4013737ceef2416282cdeb3c2e6a0a34.png)
网络编程 IO多路复用 [epoll版] (TCP网络聊天室)
//head.h 头文件 //TcpGrpSer.c 服务器端 //TcpGrpUsr.c 客户端 通过IO多路复用实现服务器在单进程单线程下可以与多个客户端交互 API epoll函数 #include<sys/epoll.h> int epoll_create(int size); 功能:创建一个epoll句柄//创建红黑树根…...
![](https://img-blog.csdnimg.cn/2868d0718ec64ab8b9a96bd64cb2f7bc.png)
【go-zero】浅析 01
“github.com/google/uuid” uuid.New().String() go-zero 文档 https://www.w3cschool.cn/gozero/ go-zero 官网 https://go-zero.dev/ 快速开始: $ mkdir go-zero-demo $ cd go-zero-demo $ go mod init go-zero-demo $ goctl api new greet $ go mod tidy Done…...
![](https://img-blog.csdnimg.cn/32c64873df7742e2bdcee79aa9c83b6c.png)
音视频——视频流H264编码格式
1 H264介绍 我们了解了什么是宏快,宏快作为压缩视频的最小的一部分,需要被组织,然后在网络之间做相互传输。 H264更深层次 —》宏块 太浅了 如果单纯的用宏快来发送数据是杂乱无章的,就好像在没有集装箱 出现之前,…...
![](https://img-blog.csdnimg.cn/725f9d28e6e54810ac5c9c187f37d6d9.png)
【使用深度学习的城市声音分类】使用从提取音频特征(频谱图)中提取的深度学习进行声音分类研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
![](https://www.ngui.cc/images/no-images.jpg)
机器学习完整路径
一个机器学习项目从开始到结束大致分为 5 步,分别是定义问题、收集数据和预处理、选择算法和确定模型、训练拟合模型、评估并优化模型性能。是一个循环迭代的过程,优秀的模型都是一次次迭代的产物。 定义问题 要剖析业务场景,设定清晰的目标…...
![](/images/no-images.jpg)
网站建设制作设计seo优化湖南/中级经济师考试
shell中可能经常能看到:echo log > /dev/null 2>&1 命令的结果可以通过%>的形式来定义输出/dev/null :代表空设备文件> :代表重定向到哪里,例如:echo "123" > /home/123.txt1 &#x…...
![](https://images2015.cnblogs.com/blog/191890/201702/191890-20170210184148729-2087483916.jpg)
做网站需要投资多少钱/百度推广入口登录
转载于:https://www.cnblogs.com/xiaoyaogege/p/6387613.html...
![](https://img-blog.csdnimg.cn/20200523122901455.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzMTQxNzI2,size_16,color_FFFFFF,t_70)
想做广告行业怎么入手/谷歌关键词优化怎么做
数组与链表 数组静态分配内存,链表动态分配内存;数组在内存中连续,链表不连续;数组利用下标定位,时间复杂度为O(1),链表定位元素时间复杂度O(n);数组插入或删除元素的时间复杂度O(n)࿰…...
![](https://img-blog.csdnimg.cn/img_convert/5e9aabbf4535aee52434078a5469af03.png#pic_center)
企业外贸营销型网站/营销页面
文章目录2、 输入控件(一)2.1 纯键盘2.1.1 QLineEdit2.1.1.1 描述2.1.1.2 控件创建2.1.1.3 输出模式2.1.1.4 提示字符串2.1.1.5 清空按钮2.1.1.6 添加操作行为2.1.1.7 自动补全2.1.1.8 输入限制2.1.1.8.1 语法2.1.1.8.2 掩码验证2.1.1.9 案例:…...
![](https://img-blog.csdnimg.cn/9a9633b9ab324dfa8202c509d207efd1.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQ2F0IEdvZCAwMDc=,size_13,color_FFFFFF,t_70,g_se,x_16#pic_center)
模型评测网站怎么做/郑州众志seo
17.Kubernetes集群Service 1.Service的介绍 不是实体服务;是一条iptables或ipvs的转发规则 2.Service的作用 通过Service为客户提供访问pod的方法,即客户端访问pod入口 Service通过pod标签与pod进行关联 3.Service的类型 (1࿰…...
![](/images/no-images.jpg)
做防水广告在哪个网站最好/夸克搜索网页版
第一步:对制品2D图及3D图的分析和消化,其内容包括以下几个方面: 1、制品的几何形状。 2、制品的尺寸、公差及设计基准。 3、制品的技术要求(即技术条件)。 4、制品所用塑料名称、缩水及颜色。 5、制品的表面要求。 第二步&am…...