C++ 异步代理库

异步代理库(或简称为“代理库”)提供了一个编程模型,通过它可以增加启用并发的应用程序开发的可靠性。 代理库是一个 C++ 模板库,它可以提升基于参与者的编程模型和进程内消息传递,以执行细化数据流任务和流水线操作任务。 代理库基于并发运行时的计划和资源管理组件生成。

代理库可提供共享状态的备选方案,方法是让您通过基于数据流(而不是控制流)的异步通信模型来连接独立的组件。 “数据流”指的是在所有必需的数据都可用时进行计算的编程模型;“控件流”指的是按预先确定的顺序进行计算的编程模型。

数据流编程模型与“消息传递”概念相关,在消息传递中,某个程序的独立组件通过发送消息与另一个程序进行通信。

代理库由三个组件组成:“异步代理”、“异步消息块”和“消息传递函数”。 代理维护状态,并使用消息块和消息传递函数与另一个组件和外部组件进行通信。 通过消息传递函数,代理可以将消息发送到外部组件和从外部组件接收消息。 异步消息块存放消息,并使通信能够以同步的方式进行通信。

下图显示了两个代理如何使用消息块和消息传递函数进行通信。 在此图中, agent1会发送一条消息, agent2使用 concurrency::send 函数和concurrency::unbounded_buffer 对象。 agent2使用 concurrency::receive 函数即可阅读邮件。 agent2 使用相同的方法向 agent1 发送消息。 虚线箭头表示代理之间的数据流。 实线箭头将代理连接到它们在其中写入或读取的消息块。

代理库的组件

本主题后面将显示实现此图的代码示例。

代理编程模型具有其他并发和同步机制(如事件)所没有的一些优点。 一个优点是:通过使用消息传递在对象之间传输状态更改,您可以隔离对共享资源的访问,从而提高可伸缩性。 消息传递的优点是它将同步绑定到数据,而不是绑定到外部的同步对象。 这简化了组件之间的数据传输,并可以消除应用程序中的编程错误。

当您有多个必须彼此异步通信的操作时,使用代理库。 使用消息块和消息传递函数,无需同步机制(如锁)即可编写并行应用程序。 这使您可以将精力集中在应用程序逻辑上。

代理编程模型通常用于创建数据管道或网络。 数据管道是一系列组件,每个组件执行一个参与更大目标的特定任务。 数据流管道中的每个组件从另一个组件接收消息时执行工作。 该工作的结果传递到管道或网络中的其他组件。 这些组件可以使用其他库(如并行模式库 (PPL))中的更细化的并发功能。

下面的示例实现本主题前面所示的图示。

C++
// basic-agents.cpp
// compile with: /EHsc
#include <agents.h>
#include <string>
#include <iostream>
#include <sstream>

using namespace concurrency;
using namespace std;

// This agent writes a string to its target and reads an integer
// from its source.
class agent1 : public agent 
{
public:
   explicit agent1(ISource<int>& source, ITarget<wstring>& target)
      : _source(source)
      , _target(target)
   {
   }

protected:
   void run()
   {
      // Send the request.
      wstringstream ss;
      ss << L"agent1: sending request..." << endl;
      wcout << ss.str();

      send(_target, wstring(L"request"));

      // Read the response.
      int response = receive(_source);

      ss = wstringstream();
      ss << L"agent1: received '" << response << L"'." << endl;
      wcout << ss.str();

      // Move the agent to the finished state.
      done();
   }

private:   
   ISource<int>& _source;
   ITarget<wstring>& _target;
};

// This agent reads a string to its source and then writes an integer
// to its target.
class agent2 : public agent 
{
public:
   explicit agent2(ISource<wstring>& source, ITarget<int>& target)
      : _source(source)
      , _target(target)
   {
   }

protected:
   void run()
   {
      // Read the request.
      wstring request = receive(_source);

      wstringstream ss;
      ss << L"agent2: received '" << request << L"'." << endl;
      wcout << ss.str();

      // Send the response.
      ss = wstringstream();
      ss << L"agent2: sending response..." << endl;
      wcout << ss.str();

      send(_target, 42);

      // Move the agent to the finished state.
      done();
   }

private:   
   ISource<wstring>& _source;
   ITarget<int>& _target;
};

int wmain()
{
   // Step 1: Create two message buffers to serve as communication channels
   // between the agents.

   // The first agent writes messages to this buffer; the second
   // agents reads messages from this buffer.
   unbounded_buffer<wstring> buffer1;

   // The first agent reads messages from this buffer; the second
   // agents writes messages to this buffer.
   overwrite_buffer<int> buffer2;

   // Step 2: Create the agents.
   agent1 first_agent(buffer2, buffer1);
   agent2 second_agent(buffer1, buffer2);

   // Step 3: Start the agents. The runtime calls the run method on
   // each agent.
   first_agent.start();
   second_agent.start();

   // Step 4: Wait for both agents to finish.
   agent::wait(&first_agent);
   agent::wait(&second_agent);
}


该示例产生下面的输出:

agent1: sending request...
agent2: received 'request'.
agent2: sending response...
agent1: received '42'.

下面的主题描述该示例中使用的功能。

异步代理

描述异步代理在执行更大计算任务中的作用。

异步消息块

描述由代理库提供的各种消息块类型。

消息传递函数

描述由代理库提供的各种消息传递例程。

如何:实现各种制造者-使用者模式

描述如何在您的应用程序中实现制造者-使用者模式。

如何:为 call 和 transformer 类提供工作函数

演示了几种提供工作函数 concurrency::call 和 concurrency::transformer 类。

如何:在数据管道中使用转换器

演示如何使用 concurrency::transformer 数据管道中的类。

如何:在已完成的任务之间选择

演示如何使用 concurrency::choice 和 concurrency::join 选择第一项任务完成搜索算法类。

如何:定期发送消息

演示如何使用 concurrency::timer 定期时间间隔发送消息的类。

如何:使用消息块筛选器

演示如何使用筛选器使异步消息块接受或拒绝消息。

并行模式库 (PPL)

描述如何在应用程序中使用各种并行模式(例如并行算法)。

并发运行时

描述可简化并行编程的并发运行时,并包含指向相关主题的链接。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值