windows C++-创建数据流代理(二)

 完整的数据流演示 

下图显示了 dataflow_agent 类的完整数据流网络:

由于 run 方法是在一个单独的线程上调用的,因此在完全连接网络之前,其他线程可以将消息发送到网络。 _source 数据成员是一个 unbounded_buffer 对象,用于缓冲从应用程序发送到代理的所有输入。 为了确保网络能够处理所有输入消息,代理会首先链接网络的内部节点,然后将该网络的起点 connector 链接到 _source 数据成员。 这可以保证在形成网络的过程中不会处理消息。

由于此示例中的网络是基于数据流,而不是基于控制流的,网络必须向代理传达它已经完成了对每个输入值的处理,并且 Sentinel 节点也已接收到它的值。 此示例使用 countdown_event 对象来指示所有输入值均已经过处理,使用 concurrency::event 对象指示 Sentinel 节点已接收到它的值。 countdown_event 类使用 event 对象指示计数器值达到零。 每当数据流网络的头收到一个值时,都会递增计数器值。 在处理输入值后,网络的每个终端节点都会递减计数器值。 代理形成数据流网络后,它会等待 Sentinel 节点设置 event 对象,还会等待 countdown_event 对象指示其计数器值已达到零。

下面的示例展示了 control_flow_agent、dataflow_agent 和 countdown_event 类。 wmain 函数创建了 control_flow_agent 和 dataflow_agent 对象,并使用 send_values 函数将一系列随机值发送到代理。

// dataflow-agent.cpp
// compile with: /EHsc 
#include <windows.h>
#include <agents.h>
#include <iostream>
#include <random>using namespace concurrency;
using namespace std;// A basic agent that uses control-flow to regulate the order of program 
// execution. This agent reads numbers from a message buffer and counts the 
// number of positive and negative values.
class control_flow_agent : public agent
{
public:explicit control_flow_agent(ISource<int>& source): _source(source){}// Retrieves the count of negative numbers that the agent received.size_t negatives() {return receive(_negatives);}// Retrieves the count of positive numbers that the agent received.size_t positives(){return receive(_positives);}protected:void run(){// Counts the number of negative and positive values that// the agent receives.size_t negative_count = 0;size_t positive_count = 0;// Read from the source buffer until we receive// the sentinel value of 0.int value = 0;      while ((value = receive(_source)) != 0){// Send negative values to the first target and// non-negative values to the second target.if (value < 0)++negative_count;else++positive_count;}// Write the counts to the message buffers.send(_negatives, negative_count);send(_positives, positive_count);// Set the agent to the completed state.done();}
private:// Source message buffer to read from.ISource<int>& _source;// Holds the number of negative and positive numbers that the agent receives.single_assignment<size_t> _negatives;single_assignment<size_t> _positives;
};// A synchronization primitive that is signaled when its 
// count reaches zero.
class countdown_event
{
public:countdown_event(unsigned int count = 0L): _current(static_cast<long>(count)) {// Set the event if the initial count is zero.if (_current == 0L)_event.set();}// Decrements the event counter.void signal() {if(InterlockedDecrement(&_current) == 0L) {_event.set();}}// Increments the event counter.void add_count() {if(InterlockedIncrement(&_current) == 1L) {_event.reset();}}// Blocks the current context until the event is set.void wait() {_event.wait();}private:// The current count.volatile long _current;// The event that is set when the counter reaches zero.event _event;// Disable copy constructor.countdown_event(const countdown_event&);// Disable assignment.countdown_event const & operator=(countdown_event const&);
};// A basic agent that resembles control_flow_agent, but uses uses dataflow to 
// perform computations when data becomes available.
class dataflow_agent : public agent
{
public:dataflow_agent(ISource<int>& source): _source(source){}// Retrieves the count of negative numbers that the agent received.size_t negatives() {return receive(_negatives);}// Retrieves the count of positive numbers that the agent received.size_t positives(){return receive(_positives);}protected:void run(){// Counts the number of negative and positive values that// the agent receives.size_t negative_count = 0;size_t positive_count = 0;// Tracks the count of active operations.countdown_event active;// An event that is set by the sentinel.event received_sentinel;//// Create the members of the dataflow network.//// Increments the active counter.transformer<int, int> increment_active([&active](int value) -> int {active.add_count();return value;});// Increments the count of negative values.call<int> negatives([&](int value) {++negative_count;// Decrement the active counter.active.signal();},[](int value) -> bool {return value < 0;});// Increments the count of positive values.call<int> positives([&](int value) {++positive_count;// Decrement the active counter.active.signal();},[](int value) -> bool {return value > 0;});// Receives only the sentinel value of 0.call<int> sentinel([&](int value) {            // Decrement the active counter.active.signal();// Set the sentinel event.received_sentinel.set();},[](int value) -> bool { return value == 0; });// Connects the _source message buffer to the rest of the network.unbounded_buffer<int> connector;//// Connect the network.//// Connect the internal nodes of the network.connector.link_target(&negatives);connector.link_target(&positives);connector.link_target(&sentinel);increment_active.link_target(&connector);// Connect the _source buffer to the internal network to // begin data flow._source.link_target(&increment_active);// Wait for the sentinel event and for all operations to finish.received_sentinel.wait();active.wait();// Write the counts to the message buffers.send(_negatives, negative_count);send(_positives, positive_count);// Set the agent to the completed state.done();}private:// Source message buffer to read from.ISource<int>& _source;// Holds the number of negative and positive numbers that the agent receives.single_assignment<size_t> _negatives;single_assignment<size_t> _positives;
};// Sends a number of random values to the provided message buffer.
void send_values(ITarget<int>& source, int sentinel, size_t count)
{// Send a series of random numbers to the source buffer.mt19937 rnd(42);for (size_t i = 0; i < count; ++i){// Generate a random number that is not equal to the sentinel value.int n;while ((n = rnd()) == sentinel);send(source, n);      }// Send the sentinel value.send(source, sentinel);   
}int wmain()
{// Signals to the agent that there are no more values to process.const int sentinel = 0;// The number of samples to send to each agent.const size_t count = 1000000;// The source buffer that the application writes numbers to and // the agents read numbers from.unbounded_buffer<int> source;//// Use a control-flow agent to process a series of random numbers.//wcout << L"Control-flow agent:" << endl;// Create and start the agent.control_flow_agent cf_agent(source);cf_agent.start();// Send values to the agent.send_values(source, sentinel, count);// Wait for the agent to finish.agent::wait(&cf_agent);// Print the count of negative and positive numbers.wcout << L"There are " << cf_agent.negatives() << L" negative numbers."<< endl;wcout << L"There are " << cf_agent.positives() << L" positive numbers."<< endl;  //// Perform the same task, but this time with a dataflow agent.//wcout << L"Dataflow agent:" << endl;// Create and start the agent.dataflow_agent df_agent(source);df_agent.start();// Send values to the agent.send_values(source, sentinel, count);// Wait for the agent to finish.agent::wait(&df_agent);// Print the count of negative and positive numbers.wcout << L"There are " << df_agent.negatives() << L" negative numbers."<< endl;wcout << L"There are " << df_agent.positives() << L" positive numbers."<< endl;
}

输出如下:

Control-flow agent:
There are 500523 negative numbers.
There are 499477 positive numbers.
Dataflow agent:
There are 500523 negative numbers.
There are 499477 positive numbers.
编译代码

复制示例代码,并将它粘贴到 Visual Studio 项目中,或粘贴到名为 dataflow-agent.cpp 的文件中,再在 Visual Studio 命令提示符窗口中运行以下命令。

cl.exe /EHsc dataflow-agent.cpp

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/54559.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网站建设中常见的网站后台开发语言有哪几种,各自优缺点都是什么?

市场上常见的网站后台开发语言有PHP、Python、JavaScript、Ruby、Java和.NET等。这些语言各有其独特的优缺点&#xff0c;适用于不同的开发场景和需求。以下是对这些语言的具体介绍&#xff1a; PHP 优点&#xff1a;PHP是一种广泛用于Web开发的动态脚本语言&#xff0c;特别适…

Diffusion models(扩散模型) 是怎么工作的

前言 给一个提示词, Midjourney, Stable Diffusion 和 DALL-E 可以生成很好看的图片&#xff0c;那么它们是怎么工作的呢&#xff1f;它们都用了 Diffusion models&#xff08;扩散模型&#xff09; 这项技术。 Diffusion models 正在成为生命科学等领域的一项尖端技术&…

基于STM32的智能花盆浇水系统设计

引言 本项目设计了一个基于STM32的智能花盆浇水系统。该系统通过土壤湿度传感器检测土壤湿度&#xff0c;当湿度低于设定阈值时&#xff0c;自动启动水泵进行浇水。它还结合了温湿度传感器用于环境监测。该项目展示了STM32在传感器集成、自动控制和节水智能化应用中的作用。 …

Nginx05-基础配置案例

零、文章目录 Nginx05-基础配置案例 1、案例需求 &#xff08;1&#xff09;有如下访问 http://192.168.119.161:8081/server1/location1 访问的是&#xff1a;index_sr1_location1.htmlhttp://192.168.119.161:8081/server1/location2 访问的是&#xff1a;index_sr1_loca…

YoloV9改进策略:BackBone改进|CAFormer在YoloV9中的创新应用,显著提升目标检测性能

摘要 在目标检测领域,模型性能的提升一直是研究者和开发者们关注的重点。近期,我们尝试将CAFormer模块引入YoloV9模型中,以替换其原有的主干网络,这一创新性的改进带来了显著的性能提升。 CAFormer,作为MetaFormer框架下的一个变体,结合了深度可分离卷积和普通自注意力…

Ansible学习之ansible-pull命令

想要知道ansible-pull是用来做什么的&#xff0c;就需要了解Ansible的工作模&#xff0c;Ansible的工作模式有两种&#xff1a; push模式 push推送&#xff0c;这是Ansible的默认模式&#xff0c;在主控机上编排好playbook文件&#xff0c;push到远程主机上来执行。pull模式 p…

远程调用的问题以及eureka原理

目录 服务调用出现的问题 问题分析 解决方案&#xff08;eureka原理&#xff09; eureka&#xff08;两个角色&#xff09; eureka的解决方案 此过程出现的问题 eureka的作用 总结 服务调用出现的问题 服务消费者该如何获取服务提供者的地址信息&#xff1f;如果有多个…

系统架构设计师论文《论企业应用系统的数据持久层架构设计》精选试读

论文真题 数据持久层&#xff08;Data Persistence Layer&#xff09;通常位于企业应用系统的业务逻辑层和数据源层之间&#xff0c;为整个项目提供一个高层、统一、安全、并发的数据持久机制&#xff0c;完成对各种数据进行持久化的编程工作&#xff0c;并为系统业务逻辑层提…

【SpringBoot】基础+JSR303数据校验

目录 一、Spring Boot概要 1. SpringBoot介绍 2. SpringBoot优点 3. SpringBoot缺点 4. 时代背景-微服务 二、Spring Boot 核心配置 1. Spring Boot配置文件分类 1.1 application.properties 1.2 application.yml 1.3 小结 2. YAML概述 3. YAML基础语法 3.1 注意事…

【教程】57帧! Mac电脑流畅运行黑神话悟空

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 1、先安装CrossOver。网上有许多和谐版&#xff0c;可自行搜索。&#xff08;pd虚拟机里运行黑神话估计够呛的&#xff09; 2、运行CrossOver&#xf…

SpringBoot上传图片实现本地存储以及实现直接上传阿里云OSS

一、本地上传 概念&#xff1a;将前端上传的文件保存到自己的电脑 作用&#xff1a;前端上传的文件到后端&#xff0c;后端存储的是一个临时文件&#xff0c;方法执行完毕会消失&#xff0c;把临时文件存储到本地硬盘中。 1、导入文件上传的依赖 <dependency><grou…

Vueron引领未来出行:2026年ADAS激光雷达解决方案上市路线图深度剖析

Vueron ADAS激光雷达解决方案路线图分析&#xff1a;2026年上市展望 Vueron近期发布的ADAS激光雷达解决方案路线图&#xff0c;标志着该公司在自动驾驶技术领域迈出了重要一步。该路线图以2026年上市为目标&#xff0c;彰显了Vueron对未来市场趋势的精准把握和对技术创新的坚定…

【瑞昱RTL8763E】刷屏

1 显示界面填充 用户创建的各个界面在 rtk_gui group 中。各界面中 icon[]表对界面进行描述&#xff0c;表中的每个元素代表一 个显示元素&#xff0c;可以是背景、小图标、字符等&#xff0c;UI_WidgetTypeDef 结构体含义如下&#xff1a; typedef struct _UI_WidgetTypeDef …

JavaSE——面向对象11:内部类(局部内部类、匿名内部类、成员内部类、静态内部类)

目录 一、内部类基本介绍 (一)内部类定义 (二)内部类基本语法 (三)内部类代码示例 (四)内部类的分类 二、局部内部类 三、匿名内部类(重要) (一)基本介绍 (二)基于接口的匿名内部类 (三)基于类的匿名内部类 (四)注意事项与使用细节 (五)匿名内部类的最佳实践——当…

UE4 材质学习笔记01(什么是着色器/PBR基础)

1.什么是shader 着色器是控制屏幕上每个像素颜色的代码&#xff0c;这些代码通常在图形处理器上运行。 现如今游戏引擎使用先进的基于物理的渲染和照明。而且照明模型模型大多数是被锁定的。 因此我们创建着色器可以控制颜色&#xff0c;法线&#xff0c;粗糙度&#xff0c;…

华为GaussDB数据库之Yukon安装与使用

一、Yukon简介 Yukon&#xff08;禹贡&#xff09;&#xff0c;基于openGauss、PostgreSQL、GaussDB数据库扩展地理空间数据的存储和管理能力&#xff0c;提供专业的GIS&#xff08;Geographic Information System&#xff09;功能&#xff0c;赋能传统关系型数据库。 Yukon 支…

重学SpringBoot3-集成Redis(六)之消息队列

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 重学SpringBoot3-集成Redis&#xff08;六&#xff09;之消息队列 1. 什么是发布/订阅&#xff08;Pub/Sub&#xff09;&#xff1f;2. 场景应用3. Spring Boot 3 整合 R…

[网络]NAT、代理服务、内网穿透、内网打洞

目录 一、NAT 1.1 NAT 技术背景 1.2 NAT IP 转换过程 1.3 NAPT&#xff08;Network Address Port Translation&#xff09; 1.地址转换表 2. NAPT&#xff08;网络地址端口转换Network Address Port Translation&#xff09; 3. NAT技术的缺陷 二、代理服务器 2.1 正向…

北交大研究突破:塑料光纤赋能低成本无摄像头AR/VR眼动追踪技术

北交大研究&#xff1a;探索无摄像头低成本AR/VR眼动追踪新路径 在AR/VR技术领域&#xff0c;眼动追踪作为一项关键技术&#xff0c;对于提升用户体验、优化渲染效率具有重要意义。然而&#xff0c;传统的眼动追踪方案多依赖于高成本的摄像头&#xff0c;这不仅增加了设备的制造…

解锁 Python 嵌套字典的奥秘:高效操作与实战应用指南

文章目录 前言&#x1f340;一、 什么是 Python 字典&#xff1f;1.1 字典的语法 &#x1f340;二、 字典的基本操作2.1 字典的创建2.2 访问字典中的值2.3 添加或修改键值对2.4 删除字典中的键值对 &#x1f340;三、 字典的遍历操作3.1 遍历字典的键3.2 遍历字典的值3.3 同时遍…