windows C++ 并行编程-实现各种生产者-消费者模式

本文介绍如何在应用程序中实现生产者-使用者模式。 在此模式下,制造者向消息块发送消息,使用者从该块读取消息。

本文演示了两种方案。 在第一种方案中,使用者必须接收生产者发送的每条消息。 在第二种方案中,使用者定期轮询数据,因此不必接收每条消息。

本文中的这两个示例都使用代理、消息块和消息传递函数将消息从生产者传输到使用者。 生产者代理使用 concurrency::send 函数将消息写入 concurrency::ITarget 对象。 使用者代理使用 concurrency::receive 函数从 concurrency::ISource 对象读取消息。 两个代理都持有一个 sentinel 值来协调处理结束。

示例:向使用者代理发送一系列数字

在此示例中,生产者代理向使用者代理发送一系列数字。 使用者将接收每一个数字并计算其平均值。 应用程序将平均值写入控制台。

此示例使用 concurrency::unbounded_buffer 对象,使生产者能够对消息进行排队。 unbounded_buffer 类实现 ITarget 和 ISource,以便生产者和使用者可以通过共享的缓冲区发送和接收消息。 send 和 receive 函数协调将数据从生产者传播到使用者的任务。

// producer-consumer-average.cpp
// compile with: /EHsc
#include <agents.h>
#include <iostream>using namespace concurrency;
using namespace std;// Demonstrates a basic agent that produces values.
class producer_agent : public agent
{
public:explicit producer_agent(ITarget<int>& target, unsigned int count, int sentinel): _target(target), _count(count), _sentinel(sentinel){}
protected:void run(){// Send the value of each loop iteration to the target buffer.while (_count > 0){send(_target, static_cast<int>(_count));--_count;}// Send the sentinel value.send(_target, _sentinel);// Set the agent to the finished state.done();}
private:// The target buffer to write to.ITarget<int>& _target;// The number of values to send.unsigned int _count;// The sentinel value, which informs the consumer agent to stop processing.int _sentinel;
};// Demonstrates a basic agent that consumes values.
class consumer_agent : public agent
{
public:explicit consumer_agent(ISource<int>& source, int sentinel): _source(source), _sentinel(sentinel){}// Retrieves the average of all received values.int average(){return receive(_average);}
protected:void run(){// The sum of all values.int sum = 0;// The count of values received.int count = 0;// Read from the source block until we receive the // sentinel value.int n;while ((n = receive(_source)) != _sentinel){sum += n;++count;}// Write the average to the message buffer.send(_average, sum / count);// Set the agent to the finished state.done();}
private:// The source buffer to read from.ISource<int>& _source;// The sentinel value, which informs the agent to stop processing.int _sentinel;// Holds the average of all received values.single_assignment<int> _average;
};int wmain()
{// Informs the consumer agent to stop processing.const int sentinel = 0;// The number of values for the producer agent to send.const unsigned int count = 100;// A message buffer that is shared by the agents.unbounded_buffer<int> buffer;// Create and start the producer and consumer agents.producer_agent producer(buffer, count, sentinel);consumer_agent consumer(buffer, sentinel);producer.start();consumer.start();// Wait for the agents to finish.agent::wait(&producer);agent::wait(&consumer);// Print the average.wcout << L"The average is " << consumer.average() << L'.' << endl;
}

本示例生成以下输出。

The average is 50.
示例:向使用者代理发送一系列股票报价

在此示例中,生产者代理向使用者代理发送一系列股票报价。 使用者代理定期读取当前报价并将其打印到控制台。

此示例与之前的示例类似,不同之处在于它使用 concurrency::overwrite_buffer 对象,使生产者能够与使用者共享一条消息。 与之前的示例中一样,overwrite_buffer 类实现 ITarget 和 ISource,以便生产者和使用者可以对共享的消息缓冲区执行操作。

// producer-consumer-quotes.cpp
// compile with: /EHsc
#include <agents.h>
#include <array>
#include <algorithm>
#include <iostream>using namespace concurrency;
using namespace std;// Demonstrates a basic agent that produces values.
class producer_agent : public agent
{
public:explicit producer_agent(ITarget<double>& target): _target(target){}
protected:void run(){// For illustration, create a predefined array of stock quotes. // A real-world application would read these from an external source, // such as a network connection or a database.array<double, 6> quotes = { 24.44, 24.65, 24.99, 23.76, 22.30, 25.89 };// Send each quote to the target buffer.for_each (begin(quotes), end(quotes), [&] (double quote) { send(_target, quote);// Pause before sending the next quote.concurrency::wait(20);});// Send a negative value to indicate the end of processing.send(_target, -1.0);// Set the agent to the finished state.done();}
private:// The target buffer to write to.ITarget<double>& _target;
};// Demonstrates a basic agent that consumes values.
class consumer_agent : public agent
{
public:explicit consumer_agent(ISource<double>& source): _source(source)      {}protected:void run(){// Read quotes from the source buffer until we receive// a negative value.double quote;while ((quote = receive(_source)) >= 0.0){// Print the quote.wcout.setf(ios::fixed);wcout.precision(2);wcout << L"Current quote is " << quote << L'.' << endl;// Pause before reading the next quote.concurrency::wait(10);}// Set the agent to the finished state.done();}
private:// The source buffer to read from.ISource<double>& _source;
};int wmain()
{// A message buffer that is shared by the agents.overwrite_buffer<double> buffer;// Create and start the producer and consumer agents.producer_agent producer(buffer);consumer_agent consumer(buffer);producer.start();consumer.start();// Wait for the agents to finish.agent::wait(&producer);agent::wait(&consumer);
}

此示例生成以下示例输出。

Current quote is 24.44.
Current quote is 24.44.
Current quote is 24.65.
Current quote is 24.99.
Current quote is 23.76.
Current quote is 22.30.
Current quote is 25.89.

与 unbounded_buffer 对象不同,receive 函数不会从 overwrite_buffer 对象中删除消息。 如果使用者在生产者覆盖消息之前多次从消息缓冲区读取,则接收方每次都会获得相同的消息。 

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【力扣每日一题——2374. 边积分最高的节点】python

2374. 边积分最高的节点 给你一个有向图&#xff0c;图中有 n 个节点&#xff0c;节点编号从 0 到 n - 1 &#xff0c;其中每个节点都 恰有一条 出边。 图由一个下标从 0 开始、长度为 n 的整数数组 edges 表示&#xff0c;其中 edges[i] 表示存在一条从节点 i 到节点 edges[…

mimics教程案例1-骨折三维重建

骨折三维重建 1 打开软件新建工程&#xff0c;将数据导入 FILE -> New Project ->找到自己的数据 ->Next ->Open 2 新建图层 SEFMENT -> New Mask ->选择阈值&#xff08;合适的阈值是可以将骨骼边缘覆盖住&#xff09;-> OK 3 使用Region Grow(区域增…

【全网最全】2024年华为杯研赛B题成品论文获取入口(后续会更新)

您的点赞收藏是我继续更新的最大动力&#xff01; 一定要点击如下的卡片&#xff0c;那是获取资料的入口&#xff01; 点击链接加入【2024华为杯研赛资料汇总】&#xff1a;https://qm.qq.com/q/hMgWngXvcQhttps://qm.qq.com/q/hMgWngXvcQ你是否在寻找数学建模比赛的突破点&a…

【无标题】HG6201M路由的超级管理密码获取

这里写自定义目录标题 1、开启telnet http://192.168.1.1/cgi-bin/telnetenable.cgi?telnetenable1&keyXXXXX 注意&#xff1a;此处的XXXXX为路由背面标签的MAC地址&#xff0c;去掉“-”&#xff0c;且大写。 成功后会显示&#xff1a;telnet开启 2、登录telnet 此处采…

GB28181协议接入SVMSPro平台

国标28181协议接入SVMSPro平台 步骤一&#xff1a;海康摄像机28181配置&#xff1b;登录海康摄像机网页进配置选项&#xff0c;左边选网络-高级设置-平台接入-类型选28181 勾选启用&#xff0c;28181协议版本选最新2016 SIP服务器ID:默认20位 34020000002000000001,也可在服务端…

SVTR文字识别

论文地址&#xff1a;https://arxiv.org/abs/2205.00159 notes&#xff1a; 论文2.5中说的N nodes&#xff0c;就是输出的类别数量&#xff0c;英文37&#xff0c;中文6625&#xff0c;英文37说的是最简单的英文文字识别任务&#xff0c;不区分大小写&#xff0c;就是26个字母…

数据库(选择题)

基本概念 数据库&#xff08;DB&#xff09;&#xff1a;长期存储在计算机内的、有组织的、可共享的数据集合。 数据库管理系统&#xff08;DBMS&#xff09;&#xff1a;它是数据库的机构&#xff0c;是一个系统软件&#xff0c;负责数据库中的数据组织、数据操纵、数据维护…

AiAutoPrediction足球网与泊松分布足球预测比赛模型介绍

AiAutoPrediction足球软件上线于2020年9月&#xff0c;是国内首家将泊松分布概率公式应用于足球比赛比分预测的软件。 AiAutoPrediction足球系列软件如下&#xff1a; AIAutoPrediction SoccerPredictor |走地大小球|走地让球|走地角球|数据分析 AiScorePredictor 泊松分布…

日志系统第一弹:日志系统介绍

日志系统第一弹&#xff1a;日志系统介绍 一、日志的重要性1.什么是日志&#xff1f;2.排查BUG3.监控系统4.监控程序性能 二、日志系统技术1.同步写日志2.异步写日志3.日志文件轮换方案1.日志分类方式2.日志轮换方案 三、项目设计1.目标2.设计1.日志消息模块2.日志格式化模块3.…

在python爬虫中xpath方式提取lxml.etree._ElementUnicodeResult转化为字符串str类型

简单提取网页中的数据时发现的 当通过xpath方式提取出需要的数据的text文本后想要转为字符串&#xff0c;但出现lxml.etree._ElementUnicodeResult的数据类型不能序列化&#xff0c;在网上查找到很多说是编码问题Unicode编码然后解码什么的&#xff1b;有些是(导入的xml库而不…

LeetCode讲解篇之1343. 大小为 K 且平均值大于等于阈值的子数组数目

文章目录 题目描述题解思路题解代码 题目描述 题解思路 题目让我们求长度为k的子数组并且该子数组的平均值大于threshold&#xff0c;对于这题&#xff0c;我们可以考虑维护一个长度为k的窗口&#xff0c;窗口不断向右滑动&#xff0c;遍历所有长度为k的子数组&#xff0c;我们…

基于Spring Boot的Java免税商品优选商城设计

第一章 绪论 1.1 课题开发的背景 从古至今&#xff0c;通过书本获取知识信息的方式完全被互联网络信息化&#xff0c;但是免税商品优选购物商城&#xff0c;对于购物商城工作来说&#xff0c;仍然是一项非常重要的工作。尤其是免税商品优选购物商城&#xff0c;传统人工记录模式…

JS | 详解浏览器存储机制cookies、sessionStorage和localStorage的区别

F12在浏览器查看 一、HTML4的本地存储——cookie 浏览器的缓存机制提供了可以将用户数据存储在客户端上的方式&#xff0c;可以利用cookie&#xff0c;session等跟服务端进行数据交互。 cookie和session cookie 和 session都是用来跟踪浏览器用户身份的会话方式。 区别&a…

如何使用 Python 的 sqlite3 模块操作 SQLite 数据库?

如何使用 Python 的 sqlite3 模块操作 SQLite 数据库&#xff1f; SQLite 是一种轻量级的数据库&#xff0c;它不需要服务器&#xff0c;数据库被存储在一个文件中&#xff0c;非常适合嵌入式系统或桌面应用程序。Python 标准库中包含了一个名为 sqlite3 的模块&#xff0c;可…

vue-入门速通

setup是最早的生命周期&#xff0c;在vue2里边的data域可以使用this调用setup里面的数据&#xff0c;但是在setup里边不能使用thisvue项目的可执行文件是index&#xff0c;另外运行前端需要npm run vue的三个模块内需要三个不同的结构&#xff0c;里边放置js代码&#xff0c;注…

【Go开发】Go语言基本语法入门:数据类型与方法定义

文章目录 环境准备一、引言二、Var关键字三、数据类型1. 整型符号表示值的范围 2. 浮点型精度范围性能 3. 布尔型4. 字符串 三、变量声明1. 指定变量类型2. 自动推导类型3. 批量声明 四、方法定义五、总结 环境准备 开发环境&#xff1a;MacOS Go版本&#xff1a;go version g…

计算机毕业设计之:基于微信小程序的校园流浪猫收养系统(源码+文档+讲解)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

「漏洞复现」灵当CRM marketing/index.php SQL注入漏洞

0x01 免责声明 请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;作者不为此承担任何责任。工具来自网络&#xff0c;安全性自测&#xff0c;如有侵权请联系删…

如何使用ssm实现社区流浪动物救助领养系统的设计与开发+vue

TOC ssm666社区流浪动物救助领养系统的设计与开发vue 第一章 课题背景及研究内容 1.1 课题背景 信息数据从传统到当代&#xff0c;是一直在变革当中&#xff0c;突如其来的互联网让传统的信息管理看到了革命性的曙光&#xff0c;因为传统信息管理从时效性&#xff0c;还是安…

Python编码系列—Python策略模式:灵活应对变化的算法策略

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…