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,一经查实,立即删除!

相关文章

Windows 编译 FFmpeg 源码详细教程

FFmpeg FFmpeg 是一个开源的多媒体框架,它包括了一整套工具和库,可以用来处理(转码、转换、录制、流式传输等)音频和视频。FFmpeg 支持广泛的音视频格式,并且可以在多种操作系统上运行,包括 Windows、Linux 和 macOS。 FFmpeg 的主要组件包括: ffmpeg:这是一个命令行工…

OpenCV视频I/O(20)视频写入类VideoWriter之用于将图像帧写入视频文件函数write()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 cv::VideoWriter::write() 函数用于将图像帧写入视频文件。 该函数/方法将指定的图像写入视频文件。图像的大小必须与打开视频编写器时指定的大…

在Python中处理文件路径

在Python中处理文件路径 下面将详细介绍如何使用 pathlib 模块来处理文件路径。我们将从创建 Path 对象、绝对路径与相对路径、访问文件路径分量&#xff0c;以及检查文件路径是否存在等几个方面进行讲解。 1. 创建 Path 对象 要使用 pathlib&#xff0c;首先需要导入模块并…

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

市场上常见的网站后台开发语言有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在传感器集成、自动控制和节水智能化应用中的作用。 …

Mongo Java Driver使用getCollection做分页查询遇到的一些坑

背景 最近在做Mongo上的表数据的迁移&#xff0c;原本应该是DBA要干的活&#xff0c;但是想着DBA排期比较长&#xff0c;加上我们开发的权限又非常有限&#xff0c;而且数据量又没有多少&#xff0c;就想着自己开发个小小的程序从旧实例上查&#xff0c;写到新实例上去算了。于…

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框架下的一个变体,结合了深度可分离卷积和普通自注意力…

计算机网络自顶向下(2)----socket编程

1.套接字 套接字是用于在计算机网络中进行通信的一种技术。它是操作系统提供的一种接口&#xff0c;通过该接口&#xff0c;应用程序可以通过网络连接进行数据的传输和接收。 套接字包含了一个IP地址和一个端口号&#xff0c;用于唯一标识一个网络连接。通过套接字&#xff0c;…

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…

nvidia英伟达显卡高刷新显示器dp接口无法进入bios的解决办法

nvidia英伟达显卡高刷新显示器dp接口无法进入bios的解决办法 问题分析 在gtx20x0之前的显卡&#xff0c;如1050ti&#xff0c;window能正常使用dp接口&#xff0c;但进入bios就无法显示&#xff08;显示器无信号输入&#xff09; 问题解决 安装NVIDIA Graphics Firmware Upda…

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 …

淘宝商品详情API接口多线程调用:解锁数据分析行业的效率新篇章

在数据分析行业&#xff0c;淘宝作为中国最大的在线购物平台&#xff0c;其商品详情数据具有极高的市场价值。然而&#xff0c;面对海量的数据&#xff0c;如何高效、稳定地获取这些数据&#xff0c;一直是数据分析师面临的重要挑战。本文将探讨如何通过多线程调用淘宝商品详情…