Biblioteca de Agentes Assíncronos
A biblioteca assíncrona de agentes (ou simplesmente a biblioteca dos agentes) fornecem um modelo de programação que permite aumentar a robustez do desenvolvimento de aplicativos simultaneidade- habilitado. A biblioteca dos agentes é a biblioteca de modelo criando c que promove uma programação baseada ator- modelo e a mensagem em processo que passa para o fluxo de dados de alta granularidade e que canaliza tarefas. A biblioteca dos agentes é baseada nos componentes de programação e gerenciamento de recursos de tempo de execução de simultaneidade.
Modelo de Programação
A biblioteca dos agentes fornece alternativas para estado compartilhado deixando o conectar componentes isolados através de um modelo de comunicação assíncrona que é baseado no fluxo de dados em vez de fluxo de controle. O fluxo de dados se refere a um modelo de programação em que as computações são feitas quando todos os dados necessários estão disponíveis; o fluxo de controle se refere a um modelo de programação em que as computações sejam feitas em uma ordem índice.
O modelo de programação de fluxo de dados está relacionado ao conceito de mensagem que transmite, onde os componentes independentes de um programa se comunicam um com o outro enviando mensagens.
A biblioteca dos agentes é composto de três componentes: agentes assíncronas, blocos assíncronas da mensageme, mensagem- passar funções. Os agentes mantêm o estado, os blocos e da mensagem de uso e as funções mensagem- passar para se comunicar um com o outro e com os componentes externos. Mensagem- passando as funções permitem que os agentes para enviar e receber mensagens ao e os componentes externos. Os blocos assíncronas de mensagem mantêm mensagens e habilita agentes para se comunicar em uma forma sincronizada.
A ilustração a seguir mostra como dois blocos agentes da mensagem de uso e funções mensagem- passar para se comunicar. Nesta ilustração, os envios de agent1 uma mensagem a agent2 usando a função de concurrency::send e um concurrency::unbounded_buffer objeto. agent2 usa a função de concurrency::receive para ler a mensagem. agent2 usam o mesmo método para enviar uma mensagem a agent1. As setas tracejadas representam o fluxo de dados entre agentes. As setas contínuas conectam os agentes aos blocos da mensagem que gravam ou lido.
Um exemplo de código que implementa esta ilustração é mostrado mais adiante neste tópico.
O modelo de programação do agente tem várias vantagens sobre outros mecanismos de simultaneidade e de sincronização, por exemplo, eventos. Uma vantagem é que o uso da mensagem que transmite para passar as alterações de estado entre objetos, você poderá isolar o acesso a recursos compartilhados, e assim melhorar a escalabilidade. Uma vantagem de passar da mensagem é ligado a sincronização dos dados em vez de cadeia de caracteres a um objeto externo de sincronização. Isso simplifica a transmissão de dados entre os componentes e pode eliminar erros de programação em seus aplicativos.
Quando Usar a Biblioteca de Agentes
Use a biblioteca dos agentes quando você tiver várias operações que devem se comunicar um com o outro de forma assíncrona. Os bloqueios da mensagem e as funções mensagem- passar permitem escrever aplicativos paralelos sem exigir mecanismos de sincronização como bloqueios. Isso permite que você se concentre na lógica do aplicativo.
O modelo de programação do agente normalmente é usado para criar pipelines de dados ou redes. Um pipeline de dados é uma série de componentes, que executa uma tarefa específica que contribui para uma meta maior. Cada componente em um pipeline de fluxo de dados executa o trabalho quando o recebe uma mensagem de outro componente. O resultado desse trabalho é passado para outros componentes no pipeline ou na rede. Componentes podem usar uma funcionalidade mais refinado de simultaneidade de outras bibliotecas, por exemplo, Biblioteca de padrões paralelos (PPL).
Exemplo
O exemplo a seguir implementa a ilustração mostrada anteriormente neste tópico.
// 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);
}
Este exemplo gera a seguinte saída:
Os tópicos a seguir descrevem a funcionalidade usada neste exemplo.
Tópicos relacionados
Agentes assíncronos
Descreve a função de agentes assíncrona em resolver tarefas de computação maiores.Blocos de mensagens assíncronos
Descreve os vários tipos do bloco de mensagem que são fornecidos pela biblioteca dos agentes.Funções de transmissão de mensagem
Descreve as várias mensagem que passa as rotinas que são fornecidas pela biblioteca dos agentes.Como implementar vários padrões de produtor-consumidor
Descreve como implementar o padrão de produtor- consumidor em seu aplicativo.Como fornecer funções de trabalho para as classes call e transformer
Ilustra vários modos de fornecer funções de trabalho às classes de concurrency::call e de concurrency::transformer .Como usar transformador em um pipeline de dados
Mostra como usar a classe de concurrency::transformer em um pipeline de dados.Como selecionar tarefas concluídas
Mostra como usar as classes de concurrency::choice e de concurrency::join para selecionar a primeira tarefa complete um algoritmo de pesquisa.Como enviar uma mensagem em um intervalo regular
Mostra como usar a classe de concurrency::timer para enviar uma mensagem em um intervalo normal.Como usar um filtro de bloco de mensagens
Demonstra como usar um filtro para habilitar um bloco de mensagens assíncrona para aceitar ou rejeitar mensagens.Biblioteca de padrões paralelos (PPL)
Descreve como usar vários padrões paralelos, como algoritmos paralelos, em seus aplicativos.Tempo de Execução de Simultaneidade
Descreve o tempo de execução de simultaneidade, o que simplifica a programação em paralelo, e contém links para os tópicos relacionados.