Sdílet prostřednictvím


Asynchronní bloků zprávy

Agenti knihovna obsahuje několik typů blok zprávy, které umožňují šíření zpráv mezi součástmi aplikace způsobem podprocesu.Tyto typy blok zprávy se často používají s různými rutiny pro předávání zpráv, například concurrency::send, concurrency::asend, concurrency::receive, a concurrency::try_receive.Další informace o předávání rutiny, které jsou definovány knihovny agenti zpráv naleznete v Funkce předávání zpráv.

Oddíly

Toto téma obsahuje následující oddíly:

  • Zdroje a cíle

  • Šíření zpráv

  • Přehled typů blok zpráv

  • Třída unbounded_buffer

  • Třída overwrite_buffer

  • Třída single_assignment

  • volání třídy

  • Třída transformátor

  • Výběr třídy

  • Třídy spojení a multitype_join

  • Třída Timer

  • Filtrování zpráv

  • Zpráva, rezervace

Zdroje a cíle

Zdroje a cíle jsou dvě důležité účastníci předávání zpráv.A zdroje odkazuje na koncového bodu odesílá zprávy sdělení.A target odkazuje na koncový bod komunikace, která přijímá zprávy.Můžete představit zdrojů, jako je čtení z koncového bodu a cíl jako koncový bod, který zapisovat do.Aplikace připojit k formuláři zdroje a cíle společně messaging sítě.

Agenti knihovna používá k reprezentaci zdroje a cíle dvě abstraktní třídy: concurrency::ISource a concurrency::ITarget.Blok zprávy typy aktu jako zdroje odvozen od ISource; blok zprávy typy aktu jako cíle odvozují z ITarget.Blok zprávy typů aktu jako zdroje a cíle odvodit z obou ISource a ITarget.

Top

Šíření zpráv

Šíření zpráv je úkon, při odeslání zprávy z jedné součásti.Při blokování zpráv nabízí zprávy, ho přijmout, odmítnout nebo odložit zprávu.Každý typ zprávy bloku jsou uloženy a přenáší zprávy různými způsoby.Například unbounded_buffer třída uchovává neomezený počet zpráv, overwrite_buffer třída uchovává zprávy najednou a třídy transformátor ukládá změněné verze jednotlivých zpráv.Tyto typy blok zpráv jsou popsány podrobněji dále v tomto dokumentu.

Při blokování zprávy přijímá zprávy, jej můžete volitelně provedení práce a zdroje, je blok zprávy předat Výsledná zpráva na jiného člena sítě.Blok zprávy pomocí funkce filtru odmítnout nechce přijímat zprávy.Filtry jsou popsány podrobněji dále v tomto tématu v části Filtrování zpráv.Blok zprávy odloží zprávu můžete rezervovat tuto zprávu a spotřebovat ji později.Zprávy rezervace je popsán podrobněji dále v tomto tématu v části Zprávy rezervace.

Knihovna agenti umožňuje bloků zprávy do asynchronně nebo synchronně předávání zpráv.Když předáte zprávu blok zprávy synchronně, například pomocí send funkci modulu runtime blokuje aktuální kontext do cílového bloku přijme nebo odmítne zprávu.Když předáte zprávu blok zprávy asynchronně, například pomocí asend modulu runtime nabízí zprávy do cílové funkci, a pokud cíl přijímá zprávy, naplánuje runtime asynchronní úkolu, šířící zprávy příjemci.K šíření zpráv způsobem spolupráce používá runtime lehký úkoly.Další informace o úkolech lehký, viz Plánovač úloh (souběžnosti Runtime).

Aplikace spojit zdroje a cíle do formuláře zasílání zpráv sítě.Obvykle propojení sítě a volání send nebo asend k předání dat na síti.Blok zprávy zdroj připojení k cíli, volejte concurrency::ISource::link_target metoda.Odpojit zdrojového bloku cíl, volejte concurrency::ISource::unlink_target metoda.Zdrojového bloku odpojit všechny své cíle, volejte concurrency::ISource::unlink_targets metoda.Jeden blok typů předdefinovaných zpráv opustí oboru nebo zničen, jej automaticky odpojí samotné bloky cíl.Některé typy zpráv blokovat omezit maximální počet cílů, které lze zapisovat.Následující část popisuje omezení, které se vztahují k blokování typů předdefinovaných zpráv.

Top

Přehled typů blok zpráv

V následující tabulce stručně popisuje roli typy bloku důležité zprávy.

  • unbounded_buffer
    Ukládá fronty zpráv.

  • overwrite_buffer
    Ukládá jednu zprávu, lze zapisovat a číst vícekrát.

  • single_assignment
    Ukládá jednu zprávu, lze jednou zapisovat a číst vícekrát.

  • volání
    Práce provádí při obdržení zprávy.

  • transformátor
    Přijímá data a odešle výsledek této práce do jiného cílového bloku vykonává práci.transformer Třídy mohou působit na různých vstupní a výstupní typy.

  • Volba
    Vybere první dostupné zprávy z několika zdrojů.

  • spojení a multitype spojení
    Počkejte na všechny zprávy přijaté ze zdrojů a pak zprávy do jiného bloku zprávy pro jednu zprávu.

  • časovač
    Odešle zprávu do cílového bloku v pravidelném intervalu.

Tyto typy blok zprávy mají různé vlastnosti, které je užitečné pro různé situace.Některé vlastnosti jsou:

  • Typ šíření: zda blok zprávy slouží jako zdroj dat nebo dat přijímač.

  • Řazení zpráv: zda blokovat zprávu zachová původní pořadí, ve kterém odeslání nebo přijetí zprávy.Každý typ bloku předdefinované zprávy zachová původní pořadí, ve kterém odesílá nebo přijímá zprávy.

  • Počet zdrojů: maximální počet zdrojů, které lze číst blok zprávy z.

  • Cíl počet: maximální počet cílů, které lze blokovat zprávy zapsat do.

Následující tabulka ukazuje, jak tyto vlastnosti se týkají různých typů blok zprávy.

Typ bloku zprávy

Typ šíření (zdroj, cíl nebo obojí)

Zpráva řazení (objednáno nebo Unordered)

Počet zdrojů

Počet cílových

unbounded_buffer

Obojí

Objednáno

Neomezeně

Neomezeně

overwrite_buffer

Obojí

Objednáno

Neomezeně

Neomezeně

single_assignment

Obojí

Objednáno

Neomezeně

Neomezeně

call

Cíl

Objednáno

Neomezeně

Nelze použít

transformer

Obojí

Objednáno

Neomezeně

1

choice

Obojí

Objednáno

10

1

join

Obojí

Objednáno

Neomezeně

1

multitype_join

Obojí

Objednáno

10

1

timer

Zdroj

Nelze použít

Nelze použít

1

Následující oddíly popisují typy blok zprávy podrobněji.

Top

Třída unbounded_buffer

Concurrency::unbounded_buffer třída představuje univerzální struktura asynchronní zasílání zpráv.Tato třída ukládá první, first out (FIFO) fronty zpráv, které lze číst z více cílů nebo napsal více zdrojů.Jakmile obdrží cílovou zprávu z unbounded_buffer objektu, že zpráva je odebrána z fronty zpráv.Proto i když unbounded_buffer objekt může mít více cílů, obdrží pouze jeden cíl každé zprávy.unbounded_buffer Třídy je užitečné, když chcete předat více zpráv do jiné součásti a součásti musí obdržet všechny zprávy.

Dd504833.collapse_all(cs-cz,VS.110).gifPříklad

Následující příklad zobrazuje základní strukturu jak pracovat s unbounded_buffer třídy.V tomto příkladu odešle tři hodnoty unbounded_buffer objektu a potom čte tyto hodnoty zpět ze stejného objektu.

// unbounded_buffer-structure.cpp
// compile with: /EHsc
#include <agents.h>
#include <iostream>

using namespace concurrency;
using namespace std;

int wmain()
{
   // Create an unbounded_buffer object that works with
   // int data.
   unbounded_buffer<int> items;

   // Send a few items to the unbounded_buffer object.
   send(items, 33);
   send(items, 44);
   send(items, 55);

   // Read the items from the unbounded_buffer object and print
   // them to the console.
   wcout << receive(items) << endl;
   wcout << receive(items) << endl;
   wcout << receive(items) << endl;
}

Tento příklad vytvoří následující výstup:

33
44
55

Kompletní příklad, který ukazuje, jak použít unbounded_buffer třídy naleznete v tématu Jak: implementovat různé vzorky producentem spotřebiteli.

Top

Třída overwrite_buffer

Concurrency::overwrite_buffer se podobá třídě unbounded_buffer třídy s výjimkou, že overwrite_buffer objekt ukládá pouze jednu zprávu.Navíc pokud cíl obdrží zprávu z overwrite_buffer objekt zprávy nejsou odebrány z vyrovnávací paměti.Více cílů proto obdržet kopii zprávy.

overwrite_buffer Třídy je užitečné, pokud chcete předat více zpráv do jiné, ale komponenta vyžaduje pouze poslední hodnota.Tato třída je také užitečné při vysílání zprávu do více součástí.

Dd504833.collapse_all(cs-cz,VS.110).gifPříklad

Následující příklad zobrazuje základní strukturu jak pracovat s overwrite_buffer třídy.V tomto příkladu odešle tři hodnoty overwrite _buffer objektu a potom čte aktuální hodnotu ze stejného objektu třikrát.Tento příklad je příklad pro podobné unbounded_buffer třídy.Však overwrite_buffer třídy ukládá pouze jednu zprávu.Kromě toho modulu runtime neodeberete zprávu z overwrite_buffer objektu po přečtení.

// overwrite_buffer-structure.cpp
// compile with: /EHsc
#include <agents.h>
#include <iostream>

using namespace concurrency;
using namespace std;

int wmain()
{
   // Create an overwrite_buffer object that works with
   // int data.
   overwrite_buffer<int> item;

   // Send a few items to the overwrite_buffer object.
   send(item, 33);
   send(item, 44);
   send(item, 55);

   // Read the current item from the overwrite_buffer object and print
   // it to the console three times.
   wcout << receive(item) << endl;
   wcout << receive(item) << endl;
   wcout << receive(item) << endl;
}

Tento příklad vytvoří následující výstup:

55
55
55

Kompletní příklad, který ukazuje, jak použít overwrite_buffer třídy naleznete v tématu Jak: implementovat různé vzorky producentem spotřebiteli.

Top

Třída single_assignment

Concurrency::single_assignment se podobá třídě overwrite_buffer třídy kromě single_assignment objektu můžete zapisovat pouze jednou.Stejně jako overwrite_buffer třídy cíl obdrží zprávu z single_assignment objekt zprávy nejsou odebrány z objektu.Více cílů proto obdržet kopii zprávy.single_assignment Třídy je užitečné, pokud chcete vysílat jedné zprávy do více součástí.

Dd504833.collapse_all(cs-cz,VS.110).gifPříklad

Následující příklad zobrazuje základní strukturu jak pracovat s single_assignment třídy.V tomto příkladu odešle tři hodnoty single_assignment objektu a potom čte aktuální hodnotu ze stejného objektu třikrát.Tento příklad je příklad pro podobné overwrite_buffer třídy.Přestože i overwrite_buffer a single_assignment třídy úložiště jedné zprávy single_assignment třídy můžete zapisovat pouze jednou.

// single_assignment-structure.cpp
// compile with: /EHsc
#include <agents.h>
#include <iostream>

using namespace concurrency;
using namespace std;

int wmain()
{
   // Create an single_assignment object that works with
   // int data.
   single_assignment<int> item;

   // Send a few items to the single_assignment object.
   send(item, 33);
   send(item, 44);
   send(item, 55);

   // Read the current item from the single_assignment object and print
   // it to the console three times.
   wcout << receive(item) << endl;
   wcout << receive(item) << endl;
   wcout << receive(item) << endl;
}

Tento příklad vytvoří následující výstup:

33
33
33

Kompletní příklad, který ukazuje, jak použít single_assignment třídy naleznete v tématu Názorný postup: Termíny provádění.

Top

volání třídy

Concurrency::call třída slouží jako zpráva přijímač, který provádí funkce práce, jakmile obdrží data.Tato funkce práce může být lambda výraz, funkce objektu nebo ukazatel na funkci.A call objektu chová jinak než voláním funkce běžné, protože funguje souběžně s jinými součástmi, které odesílat zprávy.Pokud call objekt provádí práce, jakmile obdrží zprávu, přidá zprávy do fronty.Každý call objektu procesy ve frontě zpráv v pořadí jejich doručení.

Dd504833.collapse_all(cs-cz,VS.110).gifPříklad

Následující příklad zobrazuje základní strukturu jak pracovat s call třídy.Tento příklad vytvoří call objekt, který vytiskne každou hodnotu, které obdrží v konzole.Příklad pošle do tří hodnot call objektu.Protože call objektu zpracovává zprávy na samostatný podproces, tento příklad používá také proměnné čítače a událost objektu, aby call objektu zpracovává všechny zprávy před wmain funkce vrátí.

// call-structure.cpp
// compile with: /EHsc
#include <agents.h>
#include <iostream>

using namespace concurrency;
using namespace std;

int wmain()
{
   // An event that is set when the call object receives all values.
   event received_all;

   // Counts the 
   long receive_count = 0L;
   long max_receive_count = 3L;

   // Create an call object that works with int data.
   call<int> target([&received_all,&receive_count,max_receive_count](int n) {
      // Print the value that the call object receives to the console.
      wcout << n << endl;

      // Set the event when all messages have been processed.
      if (++receive_count == max_receive_count)
         received_all.set();
   });

   // Send a few items to the call object.
   send(target, 33);
   send(target, 44);
   send(target, 55);

   // Wait for the call object to process all items.
   received_all.wait();
}

Tento příklad vytvoří následující výstup:

33
44
55

Kompletní příklad, který ukazuje, jak použít call třídy naleznete v tématu Jak: poskytují funkce pro práci na volání a transformátor třídy.

Top

Třída transformátor

Concurrency::transformer třída slouží jako obě zprávy příjemce a odesílatele zprávy.transformer Se podobá třídě call třídy, protože provádí uživatelem definovanou funkci práce, jakmile obdrží data.Však transformer třídy také odešle výsledek funkce práce objekty přijímače.Stejně jako call objektu, transformer objektu funguje souběžně s jinými součástmi, které odesílat zprávy.Pokud transformer objekt provádí práce, jakmile obdrží zprávu, přidá zprávy do fronty.Každý transformer zpracuje objekt v pořadí, ve kterém jsou přijímány zprávy ve frontě.

transformer Třídy odešle zprávu jeho jeden cíl.Pokud nastavíte _PTarget parametr do konstruktoru NULL, cíl později lze určit voláním concurrency::link_target metoda.

Na rozdíl od ostatních asynchronní zprávu bloku typů poskytované knihovny agentů transformer třídy mohou působit na různých vstupní a výstupní typy.Schopnost transformovat data z jednoho typu jiného bude transformer třídy klíčovou součástí mnoho souběžných sítí.Kromě toho můžete přidat další funkce uzamykání paralelní ve funkci práce transformer objektu.

Dd504833.collapse_all(cs-cz,VS.110).gifPříklad

Následující příklad zobrazuje základní strukturu jak pracovat s transformer třídy.Tento příklad vytvoří transformer objektu, že násobky každý vstup int hodnoty 0.33 k výrobě double hodnotu jako výstup.Příklad obdrží transformované hodnoty ze stejného transformer objektu a vytiskne je ke konzole.

// transformer-structure.cpp
// compile with: /EHsc
#include <agents.h>
#include <iostream>

using namespace concurrency;
using namespace std;

int wmain()
{
   // Create an transformer object that receives int data and 
   // sends double data.
   transformer<int, double> third([](int n) {
      // Return one-third of the input value.
      return n * 0.33;
   });

   // Send a few items to the transformer object.
   send(third, 33);
   send(third, 44);
   send(third, 55);

   // Read the processed items from the transformer object and print
   // them to the console.
   wcout << receive(third) << endl;
   wcout << receive(third) << endl;
   wcout << receive(third) << endl;
}

Tento příklad vytvoří následující výstup:

10.89
14.52
18.15

Kompletní příklad, který ukazuje, jak použít transformer třídy naleznete v tématu Jak: Použití transformátoru dat potrubí.

Top

Výběr třídy

Concurrency::choice třídy vybere první dostupné zprávy z několika zdrojů.choice Třída představuje mechanismus řízení toku namísto mechanismus datový tok (téma Asynchronní agenti knihovny popisuje rozdíly mezi datový tok a řízení toku).

Čtení z výběru objektu se podobá volání funkce rozhraní Windows API WaitForMultipleObjects po bWaitAll parametru FALSE.Však choice třídy událostí místo samotného objektu externí synchronizace sváže data.

Obvykle se používá choice třídy spolu s concurrency::receive funkce pro řízení toku aplikace.Použití choice třídy po vybírat vyrovnávací paměti zprávy, které mají různé typy.Použití single_assignment třídy po vybírat zprávy vyrovnávacích pamětí, které jsou stejného typu.

Pořadí, ve kterém propojení zdrojů choice objektu je důležitý, protože můžete určit, zpráv, které je zaškrtnuto.Zvažte například případ, kde několik vyrovnávacích pamětí zprávu obsahující zprávu, kterou chcete propojit choice objektu.choice Vybere objekt zprávy z první zdroj, který je propojen.Po propojení všech zdrojů choice pořadí, ve kterém každý zdroj, obdrží zprávu zachová objekt.

Dd504833.collapse_all(cs-cz,VS.110).gifPříklad

Následující příklad zobrazuje základní strukturu jak pracovat s choice třídy.V tomto příkladu concurrency::make_choice funkci vytvořit choice objekt, který vybírá z tří bloků zprávy.Příklad poté vypočítá různých Fibonacci čísla a ukládá každý výsledek v bloku jinou zprávu.Příklad pak vytiskne konzoly zprávu, která je založena na dokončení první operace.

// choice-structure.cpp
// compile with: /EHsc
#include <agents.h>
#include <ppl.h>
#include <iostream>

using namespace concurrency;
using namespace std;

// Computes the nth Fibonacci number.
// This function illustrates a lengthy operation and is therefore
// not optimized for performance.
int fibonacci(int n)
{
   if (n < 2)
      return n;
   return fibonacci(n-1) + fibonacci(n-2);
}

int wmain()
{
   // Although the following thee message blocks are written to one time only, 
   // this example illustrates the fact that the choice class works with 
   // different message block types.

   // Holds the 35th Fibonacci number.
   single_assignment<int> fib35;
   // Holds the 37th Fibonacci number.
   overwrite_buffer<int> fib37;
   // Holds half of the 42nd Fibonacci number.
   unbounded_buffer<double> half_of_fib42;   

   // Create a choice object that selects the first single_assignment 
   // object that receives a value.
   auto select_one = make_choice(&fib35, &fib37, &half_of_fib42);

   // Execute a few lengthy operations in parallel. Each operation sends its 
   // result to one of the single_assignment objects.
   parallel_invoke(
      [&fib35] { send(fib35, fibonacci(35)); },
      [&fib37] { send(fib37, fibonacci(37)); },
      [&half_of_fib42] { send(half_of_fib42, fibonacci(42) * 0.5); }
   );

   // Print a message that is based on the operation that finished first.
   switch (receive(select_one))
   {
   case 0:
      wcout << L"fib35 received its value first. Result = " 
            << receive(fib35) << endl;
      break;
   case 1:
      wcout << L"fib37 received its value first. Result = " 
            << receive(fib37) << endl;
      break;
   case 2:
      wcout << L"half_of_fib42 received its value first. Result = " 
            << receive(half_of_fib42) << endl;
      break;
   default:
      wcout << L"Unexpected." << endl;
      break;
   }
}

Tento příklad vytvoří následující výstup:

fib35 received its value first. Result = 9227465

Protože úkolu, vypočítá 35th Fibonacci čísla není zaručena nejprve dokončit, výstup v tomto příkladu se může lišit.

V tomto příkladu concurrency::parallel_invoke algoritmus výpočtu Fibonacci čísla paralelně.Pro více informací o parallel_invoke si prohlédněte Paralelní algoritmy.

Kompletní příklad, který ukazuje, jak použít choice třídy naleznete v tématu Jak: výběr mezi dokončené úkoly.

Top

Třídy spojení a multitype_join

Concurrency::join a concurrency::multitype_join třídy umožňují čekat každý člen sady zdrojů se zobrazí zpráva.join Třída slouží na zdrojové objekty, které mají společný typ zprávy.multitype_join Třída slouží na zdrojové objekty, které mohou mít různé typy zpráv.

Čtení join nebo multitype_join objektu se podobá volání funkce rozhraní Windows API WaitForMultipleObjects po bWaitAll parametru TRUE.Však stejně jako choice objektu, join a multitype_join objekty událostí mechanismus, spojující událostí místo samotného objektu externí synchronizace dat používají.

Čtení join vytvoří objekt std::vector objektu.Čtení multitype_join vytvoří objekt std::tuple objektu.Prvky se v těchto objektů ve stejném pořadí jako odpovídající zdroj vyrovnávací paměti jsou spojeny join nebo multitype_join objektu.Protože do vyrovnávacích pamětí pořadí, ve kterém propojení zdroje join nebo multitype_join objektu je přidružen k pořadí prvků ve výsledné vector nebo tuple objektu, doporučujeme je nelze zrušit stávající vyrovnávací paměť zdroje ze spojení.To může mít za následek neurčené chování.

Dd504833.collapse_all(cs-cz,VS.110).gifSamec Versus-samec spojení

join a multitype_join třídy podporují koncept-samec a samec spojení.A samec spojení zprávy budou k dispozici, dokud nejsou k dispozici všechny zprávy přijímá zprávy z každého z jeho zdrojů.A - samec spojení přijímá zprávy ve dvou fázích.Nejprve-samec spojení čeká ta zpráva z každého z jeho zdrojů.Za druhé po všechny zdrojové zprávy jsou k dispozici,-samec spojení pokusí vyhradit jednotlivé zprávy.Pokud jej lze rezervovat každé zprávy, spotřebovává všechny zprávy a rozšíří je na jeho cíl.V opačném vydání nebo zrušení rezervace zprávy a znovu čeká každého zdroje se zobrazí zpráva.

Samec spojení provést lépe-samec spojení, protože mohou přijímat zprávy okamžitě.Ve výjimečných případech však samec spojení může vést k zablokování.Samec spojení použijte, pokud máte více spojení, které obsahují jeden nebo více objektů sdílené zdroje.

Dd504833.collapse_all(cs-cz,VS.110).gifPříklad

Následující příklad zobrazuje základní strukturu jak pracovat s join třídy.V tomto příkladu concurrency::make_join funkci vytvořit join objektu, která přijímá ze tří single_assignment objektů.Tento příklad vypočítá různých čísel Fibonacci, každý výsledek uloží do jiného single_assignment objekt a potom vytiskne konzoly každý výsledek, join objektu v podpalubí.Tento příklad je příklad pro podobné choice třídy kromě join třídy čeká všechny zdroje bloků zprávy přijímat zprávy.

// join-structure.cpp
// compile with: /EHsc
#include <agents.h>
#include <ppl.h>
#include <iostream>

using namespace concurrency;
using namespace std;

// Computes the nth Fibonacci number.
// This function illustrates a lengthy operation and is therefore
// not optimized for performance.
int fibonacci(int n)
{
   if (n < 2)
      return n;
   return fibonacci(n-1) + fibonacci(n-2);
}

int wmain()
{
   // Holds the 35th Fibonacci number.
   single_assignment<int> fib35;
   // Holds the 37th Fibonacci number.
   single_assignment<int> fib37;
   // Holds half of the 42nd Fibonacci number.
   single_assignment<double> half_of_fib42;   

   // Create a join object that selects the values from each of the
   // single_assignment objects.
   auto join_all = make_join(&fib35, &fib37, &half_of_fib42);

   // Execute a few lengthy operations in parallel. Each operation sends its 
   // result to one of the single_assignment objects.
   parallel_invoke(
      [&fib35] { send(fib35, fibonacci(35)); },
      [&fib37] { send(fib37, fibonacci(37)); },
      [&half_of_fib42] { send(half_of_fib42, fibonacci(42) * 0.5); }
   );

   auto result = receive(join_all);
   wcout << L"fib35 = " << get<0>(result) << endl;
   wcout << L"fib37 = " << get<1>(result) << endl;
   wcout << L"half_of_fib42 = " << get<2>(result) << endl;
}

Tento příklad vytvoří následující výstup:

fib35 = 9227465
fib37 = 24157817
half_of_fib42 = 1.33957e+008

V tomto příkladu concurrency::parallel_invoke algoritmus výpočtu Fibonacci čísla paralelně.Pro více informací o parallel_invoke si prohlédněte Paralelní algoritmy.

Kompletní příklady použití join třídy naleznete v tématu Jak: výběr mezi dokončené úkoly a Názorný postup: Pomocí spojení zabránit zablokování.

Top

Třída Timer

Concurrency::timer třída slouží jako zdroj zprávy.A timer objekt odešle zprávu do cíle po uplynutí zadané období.timer Třídy je užitečné, pokud je třeba odložit odeslání zprávy nebo chcete odeslat zprávu v pravidelných intervalech.

timer Třídy odešle své zprávy pouze jeden cíl.Pokud nastavíte _PTarget parametr do konstruktoru NULL, cíl později lze určit voláním concurrency::ISource::link_target metoda.

A timer objektu můžete s opakováním nebo neopakující se.Chcete-li vytvořit opakující se časovač, true pro _Repeating parametr při volání konstruktoru.Jinak předat false pro _Repeating parametru vytvořit časovač neopakující se.Pokud je časovač opakování, pošle stejnou zprávu na jeho cíl po každém intervalu.

Vytvoří knihovnu agenti timer objekty ve stavu spuštěna.Chcete-li objekt timer, volání concurrency::timer::start metoda.Zastavit timer objekt, zničení objektu nebo volání concurrency::timer::stop metoda.Pozastavit časovač s opakováním, volejte concurrency::timer::pause metoda.

Dd504833.collapse_all(cs-cz,VS.110).gifPříklad

Následující příklad zobrazuje základní strukturu jak pracovat s timer třídy.V příkladu je timer a call objektů k hlášení průběhu déletrvající operace.

// timer-structure.cpp
// compile with: /EHsc
#include <agents.h>
#include <iostream>

using namespace concurrency;
using namespace std;

// Computes the nth Fibonacci number.
// This function illustrates a lengthy operation and is therefore
// not optimized for performance.
int fibonacci(int n)
{
   if (n < 2)
      return n;
   return fibonacci(n-1) + fibonacci(n-2);
}

int wmain()
{
   // Create a call object that prints characters that it receives 
   // to the console.
   call<wchar_t> print_character([](wchar_t c) {
      wcout << c;
   });

   // Create a timer object that sends the period (.) character to 
   // the call object every 100 milliseconds.
   timer<wchar_t> progress_timer(100u, L'.', &print_character, true);

   // Start the timer.
   wcout << L"Computing fib(42)";
   progress_timer.start();

   // Compute the 42nd Fibonacci number.
   int fib42 = fibonacci(42);

   // Stop the timer and print the result.
   progress_timer.stop();
   wcout << endl << L"result is " << fib42 << endl;
}

Tento příklad vytvoří následující výstup:

Computing fib(42)..................................................
result is 267914296

Kompletní příklad, který ukazuje, jak použít timer třídy naleznete v tématu Jak: Odeslat zprávu v pravidelných intervalech.

Top

Filtrování zpráv

Při vytvoření objektu bloku zprávy můžete zadat Funkce filtru , určuje, zda blokovat zprávu přijme nebo odmítne zprávu.Funkce Filtr je užitečný způsob, jak zaručit, že blok zprávy přijímá pouze určité hodnoty.

Následující příklad ukazuje, jak vytvořit unbounded_buffer objekt, který používá funkci Filtr přijímat pouze sudá čísla.unbounded_buffer Objekt odmítne Lichá čísla a proto nejsou rozšířena na jeho cíl bloky Lichá čísla.

// filter-function.cpp
// compile with: /EHsc
#include <agents.h>
#include <iostream>

using namespace concurrency;
using namespace std;

int wmain()
{
   // Create an unbounded_buffer object that uses a filter
   // function to accept only even numbers.
   unbounded_buffer<int> accept_evens(
      [](int n) {
         return (n%2) == 0;
      });

   // Send a few values to the unbounded_buffer object.
   unsigned int accept_count = 0;
   for (int i = 0; i < 10; ++i)
   {
      // The asend function returns true only if the target
      // accepts the message. This enables us to determine
      // how many elements are stored in the unbounded_buffer
      // object.
      if (asend(accept_evens, i))
      {
         ++accept_count;
      }
   }

   // Print to the console each value that is stored in the 
   // unbounded_buffer object. The unbounded_buffer object should
   // contain only even numbers.
   while (accept_count > 0)
   {
      wcout << receive(accept_evens) << L' ';
      --accept_count;
   }
}

Tento příklad vytvoří následující výstup:

0 2 4 6 8

Funkce filtru lze funkci lambda, ukazatel na funkci nebo funkce objektu.Každá funkce Filtr má jednu z následujících formulářů.

bool (_Type)
bool (_Type const &)

Chcete-li odstranit nepotřebné kopírování dat, formulář druhé máte agregační typ, který rozšíří se hodnota.

Podporuje filtrování zpráv datový tok programovací model, ve kterém je součástí provádět výpočty obdržíte data.Příklady použití funkcí filtrování řízení toku dat v síti předávání zpráv, viz Jak: použití filtru blokování zprávy, Názorný postup: Vytvoření agenta datový tok, a Názorný postup: Vytváření sítě zpracování obrazu.

Top

Zpráva, rezervace

Zpráva rezervace umožňuje blokovat zprávy rezervace zprávu pro pozdější použití.Rezervace zprávy obvykle nejsou přímo používá.Však zpráva Principy rezervace vám pomohou lépe porozumět chování některých typů bloku předdefinovaných zpráv.

Zvažte-samec a samec spojení.Obě tyto zprávy rezervace pomocí rezervovat zprávy pro pozdější použití.Popsáno dříve, než samec spojení přijímá zprávy ve dvou fázích.Během první fáze non samec join objekt čeká každého z jeho zdrojů se zobrazí zpráva.Samec spojení se pak pokusí vyhradit jednotlivé zprávy.Pokud jej lze rezervovat každé zprávy, spotřebovává všechny zprávy a rozšíří je na jeho cíl.V opačném vydání nebo zrušení rezervace zprávy a znovu čeká každého zdroje se zobrazí zpráva.

Spojení samec, který čte také vstupní zprávy z několika zdrojů, používá zprávy rezervace přečíst další zprávy a bude če zpráva od každého zdroje.Zvažte například spojení samec, který přijímá zprávy z bloků zprávy A a B.Pokud obdrží dvě zprávy z b samec spojení, ale ještě neobdržel zprávu od A, samec spojení uloží zprávu jedinečný identifikátor druhá zpráva z B.Po spojení samec obdrží zprávu z A a rozšíří mimo tyto zprávy používá identifikátor zprávy uložené zda druhá zpráva z B je stále k dispozici.

Při implementaci vlastních typů bloku vlastní zprávu, můžete použít zprávy rezervace.Například o tom, jak vytvořit vlastní zprávy typu bloku, viz Názorný postup: Vytváření vlastní Message Block.

Top

Viz také

Koncepty

Asynchronní agenti knihovny