Asynchronní bloky zpráv
Knihovny agentů obsahuje několik typů blok zprávy, které umožňují šíření zpráv mezi součástmi aplikace bezpečným způsobem.Tyto typy blok zprávy se často používají různé rutiny pro předávání zpráv, jako je například concurrency::send, concurrency::asend, concurrency::receive, a concurrency::try_receive.Další informace o předávání rutin, které jsou definovány pomocí knihovny agentů zpráv naleznete v tématu Funkce usnadnění.
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
Třída call
Třída transformer
Třída choice
Třídy join a multitype_join
Třída timer
Filtrování zpráv
Rezervace zprávy
Zdroje a cíle
Zdroje a cíle jsou důležité dva účastníci předávání zpráv.A zdroje odkazuje na koncový bod komunikace, který odesílá zprávy.A target odkazuje na koncový bod komunikace, která přijímá zprávy.Si můžete představit jako koncový číst ze zdroje a cíle jako koncového bodu, který zapíšete do.Aplikace připojit k formuláři zdroje a cíle společně messaging sítě.
Knihovny agentů používá dvě abstraktní třídy, které představují zdroje a cíle: concurrency::ISource a concurrency::ITarget.Typy bloků zpráv, které se chovají jako zdroje, jsou odvozeny z ISource; typy bloků zpráv, které se chovají jako cíle, jsou odvozeny z ITarget.Blok zprávy typů které působí jako zdroje a cíle jsou odvozeny z obou ISource a ITarget.
[Nahoře]
Šíření zpráv
Šíření zpráv je druhem odeslání zprávy z jedné součásti.Po bloku zprávy zprávy, můžete přijmout, odmítnout nebo odložit tuto zprávu.Každý typ bloku zprávy ukládají a přenáší zprávy různými způsoby.Například unbounded_buffer třída obsahuje neomezený počet zpráv, overwrite_buffer třída ukládá jednu zprávu v době, a třídu transformer uloží změněné verzi každé zprávy.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, může volitelně provádět práce a, pokud zdroji, je blok zprávy předat výsledné zprávy na jiného člena sítě.Blok zprávy můžete použít filtr k odmítnutí zprávy, které nechce přijmout.Filtry jsou popsány podrobněji dále v tomto tématu v části Filtrování zpráv.Blok zprávy, která odloží zprávy můžete rezervovat tuto zprávu a později ho zpracovat.Zprávy rezervace je popsán podrobněji dále v tomto tématu v části Rezervace zpráva.
Knihovny agentů asynchronně umožňuje bloky zprávy nebo synchronně předávání zpráv.Pokud předáte zprávu blok zprávy synchronně, například pomocí send funkce, modul runtime blokuje aktuální kontext do cílového bloku přijme nebo odmítne zprávu.Pokud předáte zprávu blok zprávy asynchronně, například pomocí asend funkce, modul runtime poskytuje zprávy k cíli a pokud cíl přijímá zprávy, naplánuje modul runtime asynchronní úkol, který rozšíří zpráva pro příjemce.Modul runtime používá lehké úkoly k šíření zpráv způsobem spolupráce.Další informace o úlohách, lehký, viz Plánovač úloh (Concurrency Runtime).
Aplikací spojit zdroje a cíle do formuláře messaging sítě.Obvykle, propojení sítí a volání send nebo asend k předání dat v síti.Blok zprávy zdroj připojit k cíli, zavolejte concurrency::ISource::link_target metody.Odpojení zdroje blok cíl, zavolat concurrency::ISource::unlink_target metody.Odpojení zdrojového bloku ze všech svých cílů, zavolejte concurrency::ISource::unlink_targets metody.Při blokování typů předdefinovaných zpráv opouští oboru nebo zničen, se automaticky odpojí sám z cílové bloky.Některé typy bloku zprávy omezit maximální počet cílů, které lze zapisovat.Následující část popisuje omezení, které platí předem definovaných typů bloků.
[Nahoře]
Přehled typů bloků zpráv
Následující tabulka obsahuje stručný popis role typy důležité blok zprávy.
unbounded_buffer
Jsou uloženy do fronty zprávy.overwrite_buffer
Ukládá jednu zprávu, která lze zapisovat a číst z vícekrát.single_assignment
Ukládá jednu zprávu, která může jednou zapisovat a číst z vícekrát.volání
Provádí práce při obdržení zprávy.transformátor
Práce provádí v případě, že data přijme a odešle výsledek této práce do jiného cílového bloku.transformer Třídy mohou působit na různé vstupní a výstupní typy.Volba
Vybere první dostupné zprávy z několika zdrojů.spojení a multitype spojení
Počkejte, až všechny zprávy a přijímat z několika zdrojů a pak zprávy do jedné zprávy pro jiného bloku zprávy.časovač
Odešle zprávu do cílové bloku v pravidelném intervalu.
Tyto typy blok zprávy mají odlišné vlastnosti, které je užitečné pro různé situace.Zde jsou některé charakteristiky:
Typ šíření: zda blokovat zprávy slouží jako zdroj dat a příjemce dat.
Řazení zpráv: zda blokovat zprávy udržuje původní pořadí, ve kterém zprávy odeslány nebo přijaty.Každý typ bloku zprávy předdefinované udržuje původní pořadí, ve kterém odeslání nebo přijetí zprávy.
Počet zdrojů: maximální počet zdrojů, které lze blokovat zprávy číst z.
Cílový počet: maximální počet cílů, které mohou psát blok zprávy.
Následující tabulka ukazuje, jak tyto vlastnosti se vztahují k různým typům blok zprávy.
Typ bloku zprávy |
Typ šíření (zdroj, cíl nebo obojí) |
Zpráva řazení (objednáno nebo Unordered) |
Počet zdroje |
Počet cílových |
---|---|---|---|---|
unbounded_buffer |
Obojí |
Objednané |
Neomezeně |
Neomezeně |
overwrite_buffer |
Obojí |
Objednané |
Neomezeně |
Neomezeně |
single_assignment |
Obojí |
Objednané |
Neomezeně |
Neomezeně |
call |
Cíl |
Objednané |
Neomezeně |
Nelze použít |
transformer |
Obojí |
Objednané |
Neomezeně |
1 |
choice |
Obojí |
Objednané |
10 |
1 |
join |
Obojí |
Objednané |
Neomezeně |
1 |
multitype_join |
Obojí |
Objednané |
10 |
1 |
timer |
Zdroj |
Nelze použít |
Nelze použít |
1 |
V následujících částech jsou popsány typy blok zprávy podrobněji.
[Nahoře]
Třída unbounded_buffer
Concurrency::unbounded_buffer třída představuje strukturu univerzální asynchronní zasílání zpráv.Tato třída ukládá zprávy do fronty v pořadí první dovnitř, první ven (FIFO), které mohou být zapsány do více zdrojů nebo přečteny více cíli.Pokud cíl obdrží zprávu z unbounded_buffer objekt, tato zpráva je odebrána z fronty zpráv.Proto Ačkoli unbounded_buffer objekt může mít více cílů, obdrží pouze jeden cíl každé zprávy.Třída unbounded_buffer je užitečná, pokud chcete předat více zpráv do jiné komponenty a tato komponenta musí přijmou každou zprávu.
Pří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, které mají unbounded_buffer objekt a potom nač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:
Kompletní příklad, který ukazuje, jak použít unbounded_buffer třídy naleznete v tématu Postupy: Implementace různých vzorů typu výrobce-spotřebitel.
[Nahoře]
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 není odebrána z vyrovnávací paměti.Proto více cílů obdrží kopii zprávy.
overwrite_buffer Třída je užitečné, pokud chcete předat více zpráv do jiné součásti, ale tato komponenta potřebuje pouze poslední hodnotu.Tato třída je také užitečná, pokud chcete vysílat zprávy do více komponent.
Pří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, které mají overwrite _buffer objekt a potom přečte aktuální hodnotu ze stejného objektu třikrát.Tento příklad je podobný příklad unbounded_buffer třídy.Nicméně overwrite_buffer třída obsahuje pouze jednu zprávu.Kromě toho modul runtime neodeberete zprávu z overwrite_buffer objekt po jejím 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:
Kompletní příklad, který ukazuje, jak použít overwrite_buffer třídy naleznete v tématu Postupy: Implementace různých vzorů typu výrobce-spotřebitel.
[Nahoře]
Třída single_assignment
Concurrency::single_assignment se podobá třídě overwrite_buffer třídy s výjimkou single_assignment objekt může být přepsán pouze jednou.Stejně jako třída overwrite_buffer, když cíl obdrží zprávu z objektu single_assignment, není tato zpráva z tohoto objektu odebrána.Proto více cílů obdrží kopii zprávy.single_assignment Třída je užitečné, pokud chcete vysílat více součástí jedné zprávy.
Pří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, které mají single_assignment objekt a potom přečte aktuální hodnotu ze stejného objektu třikrát.Tento příklad je podobný příklad overwrite_buffer třídy.I když jak overwrite_buffer a single_assignment třídy ukládání jedné zprávy single_assignment třídy lze zapsat na 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:
Kompletní příklad, který ukazuje, jak použít single_assignment třídy naleznete v tématu Návod: Implementace tříd future.
[Nahoře]
Třída call
Concurrency::call třída slouží jako zpráva přijímač, který provádí funkce práce poté, co obdrží data.Tato funkce práce může být lambda výrazy, funkce objektu nebo ukazatele na funkci.A call objekt se chová jinak než je běžné funkce volání protože funguje paralelně na jiné komponenty, které odesílat zprávy.Pokud call objekt provádí práci, jakmile obdrží zprávu, přidá tuto zprávu do fronty.Každý call objekt procesy ve frontě zpráv v pořadí, ve kterém jsou přijaty.
Pří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á se dostane do konzoly.Příklad pošle tři hodnoty, které mají call objektu.Protože call zprávy na samostatný podproces zpracovává objekt, v tomto příkladu se používá také proměnné čítače a události objektu, který má zajistit, aby call objekt 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:
Kompletní příklad, který ukazuje, jak použít call třídy naleznete v tématu Postupy: Poskytování pracovních funkcí třídám call a transformer.
[Nahoře]
Třída transformer
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 poté, co obdrží data vykonává práci funkce definované uživatelem.Nicméně transformer třídy také odešle výsledek práce funkce pro objekty příjemce.Podobně jako call objekt, transformer objektu působí současně na jiné komponenty, které odesílat zprávy.Pokud transformer objekt provádí práci, jakmile obdrží zprávu, přidá tuto zprávu do fronty.Každý transformer objekt zpracovává v pořadí, v jakém jsou přijímány zprávy ve frontě.
transformer Třída odešle svou zprávu na jeden cíl.Nastavíte-li _PTarget parametr do konstruktoru pro NULL, cíl dále lze určit voláním concurrency::link_target metody.
Na rozdíl od všech ostatních typů blok z asynchronní zprávy, které jsou k dispozici knihovny agentů transformer třídy mohou působit na různé vstupní a výstupní typy.Tato schopnost transformovat data z jednoho typu do jiného umožňuje 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.
Příklad
Následující příklad zobrazuje základní strukturu jak pracovat s transformer třídy.Tento příklad vytvoří transformer objekt tak, že vynásobí každou vstupní int 0.33 k získání hodnot double hodnoty jako výstup.V příkladu poté obdrží transformované hodnoty ze stejného transformer objekt a vytisknou se do konzoly.
// 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:
Kompletní příklad, který ukazuje, jak použít transformer třídy naleznete v tématu Postupy: Použití transformace v datovém kanálu.
[Nahoře]
Třída choice
Concurrency::choice třídy vybere první dostupné zprávy z několika zdrojů.choice Třída představuje mechanismus toku řízení místo mechanismus datový tok (téma Knihovna asynchronních agentů 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 parametr nastaven na FALSE.Nicméně choice třídy sváže data události, samotné místo externí synchronizace objektu.
Obvykle použijete choice třídy společně s concurrency::receive funkce pro řízení toku řízení v aplikaci.Použití choice třídy, když máte na výběr z vyrovnávací paměti zprávy, které mají různé typy.Použití single_assignment třídy, pokud máte výběr z zpráva vyrovnávací paměti, které mají stejného typu.
Pořadí, ve kterém propojíte zdroje choice objektu je důležitý, protože můžete určit, která zpráva je zaškrtnuto.Zvažte například případ, kde je několik vyrovnávacích pamětí zprávu obsahující zprávu, kterou chcete propojit choice objektu.choice Objekt zprávy vybere z první zdroj, který je propojen.Po propojení všech zdrojů choice objektu zachovává pořadí, ve kterém každý zdroj obdrží zprávu.
Příklad
Následující příklad zobrazuje základní strukturu jak pracovat s choice třídy.V tomto příkladu concurrency::make_choice funkce pro vytvoření choice objekt, který vybírá z tří bloků zprávy.V příkladu potom vypočítá různé Fibonacciho čísla a ukládá každý výsledek různých message block.V příkladu potom vytiskne do 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:
Protože úkol, který se počítá 35th Fibonacciho číslo není zaručeno dokončit první, výstup v tomto příkladu se může lišit.
V tomto příkladu concurrency::parallel_invoke algoritmus výpočtu čísla Fibonacciho paralelně.Další informace o parallel_invoke naleznete v tématu Paralelní algoritmy.
Kompletní příklad, který ukazuje, jak použít choice třídy naleznete v tématu Postupy: Výběr z dokončených úloh.
[Nahoře]
Třídy join a multitype_join
Concurrency::join a concurrency::multitype_join třídy umožňují čekat každý člen sada zdrojů 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í z join nebo multitype_join objektu se podobá volání funkce rozhraní Windows API WaitForMultipleObjects po bWaitAll parametr nastaven na TRUE.Však stejně jako choice objektu, join a multitype_join objekty používají mechanismus událostí, který sváže data události, samotné místo externí synchronizace objektu.
Čtení z join vytvoří objekt std::vector objektu.Čtení z multitype_join vytvoří objekt std::tuple objektu.Prvky se zobrazí v těchto objektech ve stejném pořadí jako jejich odpovídající vyrovnávací paměť zdroje jsou spojeny join nebo multitype_join objektu.Vzhledem k tomu, že pořadí, ve kterém propojíte zdroje vyrovnávacích pamětí do join nebo multitype_join objekt je spojen s pořadí prvků ve výsledné vector nebo tuple objekt, společnost Microsoft doporučuje, že není zrušit stávající vyrovnávací paměť zdroje ze spojení.To může mít za následek nespecifikovaný chování.
Porovnání spojení typu Greedy a Non-Greedy
join a multitype_join třídy podporují koncept-hladový a hladový spojení.A hladový spojení přijímá zprávy ze všech pramenů zprávy k dispozici, dokud nejsou k dispozici všechny zprávy.A - hladový spojení přijímá zprávy ve dvou fázích.Nejprve-hladový spojení čeká nabízený zprávy ze všech svých zdrojů.Za druhé po všechny zdrojové zprávy jsou k dispozici, spojení hladový pokusí vyhradit jednotlivé zprávy.Pokud je možné rezervovat každé zprávy, zpracovává všechny zprávy a rozšíří je na jeho cíl.Jinak ji uvolní, nebo zruší rezervace zprávu a znovu čeká každého zdroje zpráva.
Hladový spojení fungovat lépe než-hladový spojení, protože mohou přijímat zprávy okamžitě.Ve výjimečných případech však hladový spojení může vést k zablokování.Hladový spojení použijte, pokud máte více spojení, které obsahují jeden nebo více objektů sdílené zdroje.
Příklad
Následující příklad zobrazuje základní strukturu jak pracovat s join třídy.V tomto příkladu concurrency::make_join funkce pro vytvoření join objekt, který obdrží ze tří single_assignment objekty.Tento příklad vypočítá různé Fibonacciho čísla, ukládá každý výsledek jiného single_assignment objekt a potom vytiskne na konzole každého vést join objekt blokování.Tento příklad je podobný příklad choice třídy s výjimkou, že join třída čeká všechny zdroje bloků zprávy zpráva.
// 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:
V tomto příkladu concurrency::parallel_invoke algoritmus výpočtu čísla Fibonacciho paralelně.Další informace o parallel_invoke naleznete v tématu Paralelní algoritmy.
Kompletní příklady, které ukazují, jak používat join třídy naleznete v tématu Postupy: Výběr z dokončených úloh a Návod: Použití metody join k zabránění vzájemnému zablokování.
[Nahoře]
Třída timer
Concurrency::timer třída slouží jako zdroj zprávy.A timer objekt odešle zprávu do cílové po uplynutí zadaného časového úseku.timer Třída je užitečné, když musí odložit odeslání zprávy nebo chcete odeslat zprávu v pravidelných intervalech.
timer Třídy svou zprávu odešle pouze jeden cíl.Nastavíte-li _PTarget parametr do konstruktoru pro NULL, cíl dále lze určit voláním concurrency::ISource::link_target metody.
A timer objekt můžete s opakováním nebo bez opakování.Chcete-li vytvořit opakující se časovač, true k _Repeating parametr při volání konstruktoru.Jinak předat false u _Repeating parametru vytvořit časovač neopakující se.Pokud je časovač opakování, ji odeslat stejnou zprávu do svého cíle po každém intervalu.
Vytvoří knihovny agentů timer objekty ve stavu spuštěna.Chcete-li spustit objekt timer, zavolejte concurrency::timer::start metody.Zastavení timer objekt, zničení objektu nebo volání concurrency::timer::stop metody.Chcete-li pozastavit časovač s opakováním, zavolejte concurrency::timer::pause metody.
Příklad
Následující příklad zobrazuje základní strukturu jak pracovat s timer třídy.V příkladu timer a call objekty 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:
Kompletní příklad, který ukazuje, jak použít timer třídy naleznete v tématu Postupy: Odesílání zpráv v pravidelných intervalech.
[Nahoře]
Filtrování zpráv
Při vytváření objektu bloku zprávy můžete zadat funkce filter určující zda blokovat zprávu přijme nebo odmítne zprávu.Funkce filtru je vhodný způsob, jak zaručit, že blok zprávy obdrží pouze určité hodnoty.
Následující příklad ukazuje, jak vytvořit unbounded_buffer objekt, který používá filtr funkci přijmout pouze sudá čísla.unbounded_buffer Objekt odmítne lichá čísla a proto nešíří lichá čísla bloků jeho cíl.
// 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:
Funkce filtru může být lambda funkce, ukazatel funkce nebo funkce objektu.Každá funkce Filtr má jednu z těchto forem.
Odstranit nepotřebné kopírování dat, používejte druhý formulář jste agregační typ, který je rozšířena podle hodnoty.
Podporuje filtrování zpráv tok programovací model, ve kterém je součástí provádět výpočty při přijetí dat.Příklady, které řízení toku dat v síti předávání zpráv pomocí funkce filtru naleznete v tématu Postupy: Použití filtru bloku zpráv, Postupy: Vytvoření agenta toku dat, a Návod: Vytvoření sítě pro zpracování obrázků.
[Nahoře]
Rezervace zprávy
Zprávy rezervace umožňuje blok zprávy rezervace zprávu pro pozdější použití.Obvykle zprávy rezervace nepoužívá přímo.Však zpráva Principy rezervace vám pomohou lépe porozumět chování některých typů předdefinovaných zpráv blok.
Zvažte-hladový a hladový spojení.Obě tyto zprávy rezervace pomocí rezervace zprávy pro pozdější použití.Popsáno dříve, než hladový spojení přijímá zprávy ve dvou fázích.Během první fáze non hladový join všech pramenů zpráva čeká objektu.Hladový spojení se poté pokusí vyhradit jednotlivé zprávy.Pokud je možné rezervovat každé zprávy, zpracovává všechny zprávy a rozšíří je na jeho cíl.Jinak ji uvolní, nebo zruší rezervace zprávu a znovu čeká každého zdroje zpráva.
Hladový spojení, které také čte vstupní zprávy z několika zdrojů, rezervace zpráva používá ke čtení další zprávy a bude čekat na zprávy z každého zdroje.Zvažte například hladový spojení, která přijímá zprávy z bloků zprávy A a B.Pokud obdrží dvě zprávy od B hladový spojení, ale ještě neobdržel zprávu od A, hladový spojení uloží identifikátor jedinečný zpráva druhá zpráva od B.Po spojení hladový obdrží zprávu od A a rozšíří tyto zprávy používá identifikátor uložené zprávy a zjistit, zda druhá zpráva od B je stále k dispozici.
Při implementaci vlastních typů blok vlastní zprávu, můžete použít zprávy rezervace.Příklad, jak vytvořit blok typ vlastní zprávy, viz Návod: Vytvoření vlastního bloku zpráv.
[Nahoře]