当前位置: 首页 > news >正文

windows C++ 并行编程-异步消息块(四)

join 和 multitype_join 类

concurrency::join 和 concurrency::multitype_join 类允许你等待一组源中的每个成员接收消息。 join 类作用于具有通用消息类型的源对象。 multitype_join 类作用于可具有不同消息类型的源对象。

读取 join 或 multitype_join 对象类似于在将 bWaitAll 参数设置为 TRUE 的情况下调用 Windows API 函数 WaitForMultipleObjects。 但是,与 choice 对象一样,join 和 multitype_join 对象使用将数据绑定到事件本身而不是外部同步对象的事件机制。

读取 join 对象会生成 std::vector 对象。 读取 multitype_join 对象会生成 std::tuple 对象。 元素按照其相应源缓冲区链接到 join 或 multitype_join 对象的相同顺序出现在这些对象中。 由于将源缓冲区链接到 join 或 multitype_join 对象的顺序与生成的 vector 或 tuple 对象中的元素顺序相关联,因此我们建议不要从联接中取消链接现有的源缓冲区。 这样做可能会导致未指定的行为。

贪婪与非贪婪联接

join 和 multitype_join 类支持贪婪和非贪婪联接的概念。 当消息可用时,贪婪联接会接受其每个源中的消息,直到所有消息都可用。 非贪婪联接分两个阶段接收消息。 首先,非贪婪联接会一直等到从其每个源为其提供消息。 然后,在所有源消息都可用后,非贪婪联接会尝试保留其中的每条消息。 如果它可以保留每条消息,则会使用所有消息并将其传播到目标。 否则,它会释放或取消消息保留,并再次等待每个源接收消息。

贪婪联接比非贪婪联接的性能更好,因为它们立即接受消息。 但是,在极少数情况下,贪婪联接会导致死锁。 如果有多个联接包含一个或多个共享源对象,请使用非贪婪联接。

示例

以下示例使用基本结构来演示如何使用 join 类。 此示例使用 concurrency::make_join 函数创建一个从三个 single_assignment 对象接收消息的 join 对象。 此示例计算不同的斐波那契数,将每个结果存储在不同的 single_assignment 对象中,然后将 join 对象保存的每个结果输出到控制台。 此示例类似于 choice 类的示例,不同之处在于,join 类会等待所有源消息块接收消息。

// join-structure.cpp
// compile with: /EHsc
#include <agents.h>
#include <ppl.h>
#include <iostream>using namespace concurrency;
using namespace std;// Computes the nth Fibonacci number.
// This function illustrates a lengthy operation and is therefore
// not optimized for performance.
int fibonacci(int n)
{if (n < 2)return n;return fibonacci(n-1) + fibonacci(n-2);
}int wmain()
{// Holds the 35th Fibonacci number.single_assignment<int> fib35;// Holds the 37th Fibonacci number.single_assignment<int> fib37;// Holds half of the 42nd Fibonacci number.single_assignment<double> half_of_fib42;   // Create a join object that selects the values from each of the// single_assignment objects.auto join_all = make_join(&fib35, &fib37, &half_of_fib42);// Execute a few lengthy operations in parallel. Each operation sends its // result to one of the single_assignment objects.parallel_invoke([&fib35] { send(fib35, fibonacci(35)); },[&fib37] { send(fib37, fibonacci(37)); },[&half_of_fib42] { send(half_of_fib42, fibonacci(42) * 0.5); });auto result = receive(join_all);wcout << L"fib35 = " << get<0>(result) << endl;wcout << L"fib37 = " << get<1>(result) << endl;wcout << L"half_of_fib42 = " << get<2>(result) << endl;
}

该示例产生下面的输出:

fib35 = 9227465fib37 = 24157817half_of_fib42 = 1.33957e+008

此示例使用 concurrency::parallel_invoke 算法并行计算斐波那契数。

timer 类

concurrency::timer 类充当消息源。 timer 对象在指定的时间段过后向目标发送消息。 必须延迟发送消息或要按固定的间隔发送消息时,timer 类很有用。

timer 类将其消息仅发送到一个目标。 如果将构造函数中的 _PTarget 参数设置为 NULL,则稍后可以通过调用 concurrency::ISource::link_target 方法来指定目标。

timer 对象可以重复或不重复。 若要创建重复计时器,请在调用构造函数时为 _Repeating 参数传递 true。 否则,请为 _Repeating 参数传递 false 以创建非重复计时器。 如果计时器是重复的,则它会在每个间隔后向其目标发送相同的消息。

代理库创建处于未启动状态的 timer 对象。 若要启动 timer 对象,请调用 concurrency::timer::start 方法。 若要停止 timer 对象,请销毁该对象或调用 concurrency::timer::stop 方法。 若要暂停重复计时器,请调用 concurrency::timer::pause 方法。

示例

以下示例使用基本结构来演示如何使用 timer 类。 该示例使用 timer 和 call 对象来报告长时间运行的操作的进度。

// timer-structure.cpp
// compile with: /EHsc
#include <agents.h>
#include <iostream>using namespace concurrency;
using namespace std;// Computes the nth Fibonacci number.
// This function illustrates a lengthy operation and is therefore
// not optimized for performance.
int fibonacci(int n)
{if (n < 2)return n;return fibonacci(n-1) + fibonacci(n-2);
}int wmain()
{// Create a call object that prints characters that it receives // to the console.call<wchar_t> print_character([](wchar_t c) {wcout << c;});// Create a timer object that sends the period (.) character to // the call object every 100 milliseconds.timer<wchar_t> progress_timer(100u, L'.', &print_character, true);// Start the timer.wcout << L"Computing fib(42)";progress_timer.start();// Compute the 42nd Fibonacci number.int fib42 = fibonacci(42);// Stop the timer and print the result.progress_timer.stop();wcout << endl << L"result is " << fib42 << endl;
}

此示例产生以下示例输出:

Computing fib(42)..................................................result is 267914296

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Java集合(List篇)
  • fiddler抓包06_抓取https请求(chrome)
  • 财富通公司开发维修售后小程序,解决售后维修问题
  • 【摘抄】软件工程师认知
  • 量子噪声流加密(一:整体框架描述)
  • 惠海H6118 DC-DC 降压恒流芯片30V36v40V48V降12V9V24V36V 1.2A大电流 调光降压芯片IC舞台灯
  • 学习CubeIDE——外设中断开发
  • 活动目录安全
  • go注册中心Eureka,注册到线上和线下,都可以访问
  • 聊聊Thread Local Storage
  • uni-app页面调用接口和路由(四)
  • 【ShuQiHere】 探索计算机视觉的世界:从基础到应用
  • 在线安全干货|如何更改IP地址?
  • 2024年最新苹果cms升级插件【泛目录专用】
  • 笔记整理—内核!启动!—linux应用编程、网络编程部分(1)API概述与文件I/O
  • 【腾讯Bugly干货分享】从0到1打造直播 App
  • 〔开发系列〕一次关于小程序开发的深度总结
  • iOS高仿微信项目、阴影圆角渐变色效果、卡片动画、波浪动画、路由框架等源码...
  • JavaScript 事件——“事件类型”中“HTML5事件”的注意要点
  • mysql innodb 索引使用指南
  • Mysql优化
  • puppeteer stop redirect 的正确姿势及 net::ERR_FAILED 的解决
  • UMLCHINA 首席专家潘加宇鼎力推荐
  • Vue.js 移动端适配之 vw 解决方案
  • vue-router 实现分析
  • 关键词挖掘技术哪家强(一)基于node.js技术开发一个关键字查询工具
  • 面试题:给你个id,去拿到name,多叉树遍历
  • 一加3T解锁OEM、刷入TWRP、第三方ROM以及ROOT
  • 自制字幕遮挡器
  • Spring Batch JSON 支持
  • # C++之functional库用法整理
  • #70结构体案例1(导师,学生,成绩)
  • #每天一道面试题# 什么是MySQL的回表查询
  • (¥1011)-(一千零一拾一元整)输出
  • (二)Kafka离线安装 - Zookeeper下载及安装
  • (附源码)springboot 校园学生兼职系统 毕业设计 742122
  • (六)库存超卖案例实战——使用mysql分布式锁解决“超卖”问题
  • (七)c52学习之旅-中断
  • (四)linux文件内容查看
  • .NET Core6.0 MVC+layui+SqlSugar 简单增删改查
  • .Net Core和.Net Standard直观理解
  • .NET Micro Framework 4.2 beta 源码探析
  • .NET 跨平台图形库 SkiaSharp 基础应用
  • .NetCore Flurl.Http 升级到4.0后 https 无法建立SSL连接
  • .netcore 如何获取系统中所有session_如何把百度推广中获取的线索(基木鱼,电话,百度商桥等)同步到企业微信或者企业CRM等企业营销系统中...
  • .NET简谈设计模式之(单件模式)
  • /etc/skel 目录作用
  • @Builder注释导致@RequestBody的前端json反序列化失败,HTTP400
  • @DependsOn:解析 Spring 中的依赖关系之艺术
  • [ 2222 ]http://e.eqxiu.com/s/wJMf15Ku
  • [8-27]正则表达式、扩展表达式以及相关实战
  • [AI]文心一言出圈的同时,NLP处理下的ChatGPT-4.5最新资讯
  • [FlareOn6]Overlong
  • [Flink]三、Flink1.13
  • [Flutter]打包IPA