Aracılığıyla paylaş


Zaman Uyumsuz Aracılar Kitaplığı

Zaman Uyumsuz Aracılar Kitaplığı (veya yalnızca Aracılar Kitaplığı), eşzamanlılık özellikli uygulama geliştirmenin sağlamlığını artırmanıza olanak tanıyan bir programlama modeli sağlar. Aracılar Kitaplığı, daha ayrıntılı veri akışı ve kanal oluşturma görevleri için aktör tabanlı bir programlama modelini ve işlem içi ileti geçirmeyi yükselten bir C++ şablon kitaplığıdır. Aracılar Kitaplığı, Eşzamanlılık Çalışma Zamanı'nın zamanlama ve kaynak yönetimi bileşenlerini kullanır.

Programlama Modeli

Aracılar Kitaplığı, denetim akışı yerine veri akışını temel alan zaman uyumsuz bir iletişim modeli aracılığıyla yalıtılmış bileşenleri bağlamanıza olanak sağlayarak paylaşılan duruma alternatifler sağlar. Veri akışı , gerekli tüm veriler kullanılabilir olduğunda hesaplamaların yapıldığı bir programlama modelini ifade eder; denetim akışı , hesaplamaların önceden belirlenmiş bir sırada yapıldığı bir programlama modelini ifade eder.

Veri akışı programlama modeli, bir programın bağımsız bileşenlerinin ileti göndererek birbirleriyle iletişim kurduğu ileti geçirme kavramıyla ilgilidir.

Aracılar Kitaplığı üç bileşenden oluşur: zaman uyumsuz aracılar, zaman uyumsuz ileti blokları ve ileti geçirme işlevleri. Aracılar durumu korur ve birbirleriyle ve dış bileşenlerle iletişim kurmak için ileti bloklarını ve ileti geçirme işlevlerini kullanır. İleti geçirme işlevleri, aracıların dış bileşenlere ileti gönderip almasını sağlar. Zaman uyumsuz ileti blokları iletileri tutar ve aracıların eşitlenmiş bir şekilde iletişim kurmasını sağlar.

Aşağıdaki çizimde, iki aracının iletişim kurmak için ileti bloklarını ve ileti geçirme işlevlerini nasıl kullandığı gösterilmektedir. Bu çizimde, agent1 concurrency::send işlevini ve concurrency::unbounded_buffer nesnesini kullanarak adresine bir ileti agent2 gönderir. agent2iletiyi okumak için concurrency::receive işlevini kullanır. agent2 adresine ileti agent1göndermek için aynı yöntemi kullanır. Kesikli oklar aracılar arasındaki veri akışını temsil eder. Düz oklar, aracıları yazdıkları veya okudukları ileti bloklarına bağlar.

The components of the Agents Library.

Bu çizimi uygulayan bir kod örneği, bu konunun ilerleyen bölümlerinde gösterilmiştir.

Aracı programlama modelinin, olaylar gibi diğer eşzamanlılık ve eşitleme mekanizmalarına göre çeşitli avantajları vardır. Bunun bir avantajı, nesneler arasında durum değişikliklerini iletmek için ileti geçirmeyi kullanarak paylaşılan kaynaklara erişimi yalıtabilmeniz ve böylece ölçeklenebilirliği geliştirebilmenizdir. İleti geçirmenin bir avantajı, eşitlemeyi dış eşitleme nesnesine bağlamak yerine verilere bağlamasıdır. Bu, bileşenler arasında veri iletimini basitleştirir ve uygulamalarınızdaki programlama hatalarını ortadan kaldırır.

Aracılar Kitaplığı Kullanılacağı Zaman

Birbiriyle zaman uyumsuz olarak iletişim kurması gereken birden çok işleminiz olduğunda Aracılar kitaplığını kullanın. İleti blokları ve ileti geçirme işlevleri, kilitler gibi eşitleme mekanizmaları gerektirmeden paralel uygulamalar yazmanızı sağlar. Bu, uygulama mantığına odaklanmanızı sağlar.

Aracı programlama modeli genellikle veri işlem hatları veya ağlar oluşturmak için kullanılır. Veri işlem hattı, her biri daha büyük bir hedefe katkıda bulunan belirli bir görevi gerçekleştiren bir dizi bileşendir. Veri akışı işlem hattındaki her bileşen, başka bir bileşenden ileti aldığında iş gerçekleştirir. Bu çalışmanın sonucu, işlem hattındaki veya ağdaki diğer bileşenlere geçirilir. Bileşenler, paralel desen kitaplığı (PPL) gibi diğer kitaplıklardan daha ayrıntılı eşzamanlılık işlevselliği kullanabilir.

Örnek

Aşağıdaki örnek, bu konunun önceki bölümlerinde gösterilen çizimi uygular.

// 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);
}

Bu örnek aşağıdaki çıkışı oluşturur:

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

Aşağıdaki konularda, bu örnekte kullanılan işlevler açıklanmaktadır.

Zaman Uyumsuz Aracılar
Daha büyük bilgi işlem görevlerinin çözümünde zaman uyumsuz aracıların rolünü açıklar.

Zaman Uyumsuz İleti Blokları
Aracılar Kitaplığı tarafından sağlanan çeşitli ileti bloğu türlerini açıklar.

İleti Geçirme İşlevleri
Aracılar Kitaplığı tarafından sağlanan çeşitli ileti geçirme yordamlarını açıklar.

Nasıl yapılır: Çeşitli Üretici-Tüketici Desenlerini Uygulama
Uygulamanızda üretici-tüketici deseninin nasıl uygulanacaklarını açıklar.

Nasıl yapılır: call ve transformer Sınıflarına İş İşlevleri Sağlama
Eşzamanlılık::call ve concurrency::transformer sınıflarına iş işlevleri sağlamanın çeşitli yollarını gösterir.

Nasıl yapılır: Veri İşlem Hattında transformer Kullanma
Bir veri işlem hattında concurrency::transformer sınıfının nasıl kullanılacağını gösterir.

Nasıl yapılır: Tamamlanan Görevler Arasında Seçim Yapma
Arama algoritmasını tamamlamak için ilk görevi seçmek için eşzamanlılık::choice ve concurrency::join sınıflarının nasıl kullanılacağını gösterir.

Nasıl yapılır: Düzenli Aralıkla İleti Gönderme
Düzenli aralıklarla ileti göndermek için eşzamanlılık::timer sınıfının nasıl kullanılacağını gösterir.

Nasıl yapılır: İleti Bloğu Filtresini Kullanma
Zaman uyumsuz ileti bloğunun iletileri kabul veya reddetmesini sağlamak için filtrenin nasıl kullanılacağını gösterir.

Paralel Desen Kitaplığı (PPL)
Uygulamalarınızda paralel algoritmalar gibi çeşitli paralel desenlerin nasıl kullanılacağını açıklar.

Eşzamanlılık Çalışma Zamanı
Paralel programlamayı basitleştiren ve ilgili konulara bağlantılar içeren Eşzamanlılık Çalışma Zamanı'nı açıklar.