Sdílet prostřednictvím


Paralelní kontejnerů a objektů

Paralelní knihovnu vzorků (PPL) obsahuje několik kontejnerů a objektů, které poskytují přístup k podprocesu jejich prvků.

A souběžných kontejneru poskytuje bezpečné souběžný přístup k nejdůležitějších operací.Podobná funkce těchto kontejnerů, které jsou k dispozici standardní šablonu knihovny (STL).Například concurrency::concurrent_vector se podobá třídě std::vector třídy kromě concurrent_vector třídy umožňuje připojit paralelně prvky.Souběžné kontejnery použijte, pokud máte paralelní kód, který vyžaduje pro čtení a zápis do stejného kontejneru.

A souběžných objektu je souběžně sdílených mezi součástmi.Proces, který vypočítá stát souběžných objektu paralelně stejný výsledek jako jiný proces, který vypočítá sériově stejného státu.Concurrency::combinable je příkladem souběžných objekt typu třída.combinable Třída umožňuje provádět výpočty paralelně a pak zkombinovat tyto výpočty do konečného výsledku.Použití souběžných objektů pomocí mechanismu synchronizace, například mutex by jinak synchronizovat přístup ke sdílené proměnné nebo zdroj.

Oddíly

Toto téma popisuje následující paralelní kontejnery a objekty podrobně.

Souběžné kontejnery:

  • Třída concurrent_vector

    • Rozdíly mezi concurrent_vector a vektorové

    • Souběžnost bezpečné operace

    • Výjimka bezpečnosti

  • Třída concurrent_queue

    • Rozdíly mezi concurrent_queue a fronty

    • Souběžnost bezpečné operace

    • Podpora iterace

  • Třída concurrent_unordered_map

    • Rozdíly mezi concurrent_unordered_map a unordered_map

    • Souběžnost bezpečné operace

  • Třída concurrent_unordered_multimap

  • Třída concurrent_unordered_set

  • Třída concurrent_unordered_multiset

Souběžné objekty:

  • Třída combinable

    • Metody a funkce

    • Příklady

Třída concurrent_vector

Concurrency::concurrent_vector třída je třída kontejneru sekvence, stejně jako std::vector třídy, umožňuje přístup náhodně jeho prvky.concurrent_vector Třídy umožňuje připojit souběžnosti bezpečné a prvek přístup operací.Přidat existující ukazatele nebo u iterátorů nečiní operací.Iterační přístup a křížovou kontrolu operace jsou také bezpečné souběžnosti.

Dd504906.collapse_all(cs-cz,VS.110).gifRozdíly mezi concurrent_vector a vektorové

concurrent_vector Třídy podobá vector třídy.Složitost přidávací, prvek přístup a iterace operace přístupu na concurrent_vector objektu jsou stejné jako pro vector objektu.Následující body popisují kde concurrent_vector se liší od vector:

  • Přidat prvek přístup, iterační přístup a iterace křížovou kontrolu operací na concurrent_vector objektu jsou bezpečné souběžnosti.

  • Prvky můžete přidat pouze do konce concurrent_vector objektu.concurrent_vector Třídy neposkytuje insert metoda.

  • A concurrent_vector objekt pomocí přesunout sémantiku při připojení k ní.

  • concurrent_vector Třídy neposkytuje erase nebo pop_back metod.Stejně jako vector, použít zrušte metoda odebrat všechny prvky z concurrent_vector objektu.

  • concurrent_vector Třídy neukládá prvky souvisle v paměti.Proto nelze použít concurrent_vector třídy všechny způsoby pomocí matice.Například pro proměnnou nazvanou v typu concurrent_vector, výraz &v[0]+2 vytváří nedefinované chování.

  • concurrent_vector Třída definuje grow_by a grow_to_at_least metod.Tyto metody připomínají velikost metodou, s výjimkou, že jsou bezpečné souběžnosti.

  • A concurrent_vector objektu nevede k přemístění prvky při k němu přidat nebo změnit jeho velikost.To umožňuje stávajících ukazatelů a u iterátorů zůstává v platnosti během souběžných operací.

  • Modul runtime nedefinuje speciální verzi concurrent_vector typu bool.

Dd504906.collapse_all(cs-cz,VS.110).gifSouběžnost bezpečné operace

Všechny metody, které připojit k nebo zvětšit velikost concurrent_vector objektu nebo prvku v přístupu concurrent_vector objektů, které jsou bezpečné souběžnosti.Výjimkou z tohoto pravidla je resize metoda.

Následující tabulka obsahuje běžné concurrent_vector metody a operátory, které jsou bezpečné souběžnosti.

na

Konec

operátor]

začít

přední

push_back

zpět

grow_by

rbegin

kapacita

grow_to_at_least

rend

prázdné

max_size

size

Operace, které poskytuje modul runtime pro kompatibilitu s STL, například reserve, nejsou bezpečné souběžnosti.Následující tabulka obsahuje běžné metody a subjekty, které nejsou bezpečné souběžnosti.

přiřadit

rezervovat

Vymazat

změnit velikost

operátor =

shrink_to_fit

Operace, které změnit hodnotu existující prvky nejsou bezpečné souběžnosti.Například použít objekt synchronizace reader_writer_lock synchronizovat souběžných čtení a zápis stejný datový prvek objektu.Další informace o synchronizaci objektů viz Synchronizace struktury dat.

Při převedení existujícího kódu, který používá vector pomocí concurrent_vector, souběžných operací může způsobit chování aplikace můžete změnit.Například zvažte následující program, který současně provádí dva úkoly concurrent_vector objektu.První úkol připojí další prvky concurrent_vector objektu.Druhý úkol vypočítá součet všech prvků ve stejném objektu.

// parallel-vector-sum.cpp
// compile with: /EHsc
#include <ppl.h>
#include <concurrent_vector.h>
#include <iostream>

using namespace concurrency;
using namespace std;

int wmain()
{
   // Create a concurrent_vector object that contains a few
   // initial elements.
   concurrent_vector<int> v;
   v.push_back(2);
   v.push_back(3);
   v.push_back(4);

   // Perform two tasks in parallel.
   // The first task appends additional elements to the concurrent_vector object.
   // The second task computes the sum of all elements in the same object.

   parallel_invoke(
      [&v] { 
         for(int i = 0; i < 10000; ++i)
         {
            v.push_back(i);
         }
      },
      [&v] {
         combinable<int> sums;
         for(auto i = begin(v); i != end(v); ++i) 
         {
            sums.local() += *i;
         }     
         wcout << L"sum = " << sums.combine(plus<int>()) << endl;
      }
   );
}

Přestože end metoda je bezpečná souběžnosti souběžných volání push_back metoda způsobí vrácenou hodnotu end změnit.Počet prvků, které projde iterace je neurčitá.Proto tento program může způsobit jiné výsledky při každém spuštění.

Dd504906.collapse_all(cs-cz,VS.110).gifVýjimka bezpečnosti

Pokud operace růstu nebo přiřazení výjimku, stav concurrent_vector objektu stává neplatným.Chování concurrent_vector není definován objekt, který je v neplatném stavu, pokud není uvedeno jinak.Se objekt však vždy uvolní paměť, která přiděluje objektu, i když objekt je v neplatném stavu.

Datový typ elementy vector _Ty, musí splňovat následující požadavky.Jinak chování concurrent_vector třídy není definován.

  • Musí se objekt není vyvolána.

  • Pokud vyvolá konstruktor výchozí nebo kopie, pomocí nesmí být deklarován se objekt virtual klíčové slovo a musí pracovat správně paměť inicializována nula.

Top

Třída concurrent_queue

Concurrency::concurrent_queue třídy, stejně jako std::queue třídy, umožňuje přístup k jeho přední a zadní prvky.concurrent_queue Třída umožňuje bezpečné souběžnosti zařazení a vyřazení z fronty operace.concurrent_queue Třídy také poskytuje podporu iterace, která není bezpečná souběžnosti.

Dd504906.collapse_all(cs-cz,VS.110).gifRozdíly mezi concurrent_queue a fronty

concurrent_queue Třídy podobá queue třídy.Následující body popisují kde concurrent_queue se liší od queue:

  • Zařazení a vyřazení z fronty operace na concurrent_queue objektu jsou bezpečné souběžnosti.

  • concurrent_queue Třída poskytuje podporu iterace, který není bezpečný souběžnosti.

  • concurrent_queue Třídy neposkytuje front nebo pop metod.concurrent_queue Třídy definováním nahradí tyto metody try_pop metoda.

  • concurrent_queue Třídy neposkytuje back metoda.Proto nelze odkazovat na konec fronty.

  • concurrent_queue Třída poskytuje unsafe_size metody namísto size metoda.unsafe_size Metoda není bezpečné souběžnosti.

Dd504906.collapse_all(cs-cz,VS.110).gifSouběžnost bezpečné operace

Všechny metody tohoto zařazení do nebo vyřazení z fronty z concurrent_queue objektu jsou bezpečné souběžnosti.

Následující tabulka obsahuje běžné concurrent_queue metody a operátory, které jsou bezpečné souběžnosti.

prázdné

nabízenou replikaci

get_allocator

try_pop

Přestože empty metoda je bezpečná souběžnosti, souběžné operace může způsobit zvětšení nebo zmenšení před fronty empty metoda vrátí.

Následující tabulka obsahuje běžné metody a subjekty, které nejsou bezpečné souběžnosti.

Vymazat

unsafe_end

unsafe_begin

unsafe_size

Dd504906.collapse_all(cs-cz,VS.110).gifPodpora iterace

concurrent_queue Poskytuje u iterátorů, které nejsou bezpečné souběžnosti.Doporučujeme použít tyto u iterátorů pouze ladění.

A concurrent_queue iterační přenosech směrem dopředu pouze prvky.Následující tabulka uvádí operátory, že každá iterace podporuje.

Operátor

Description

operátor ++

Zálohy na další položku ve frontě.Tento operátor je přetížena poskytnout sémantiku pre-increment i post-increment.

operátor *

Získá odkaz na aktuální položky.

operátor - >

Načte ukazatel aktuální položky.

Top

Třída concurrent_unordered_map

Concurrency::concurrent_unordered_map třída je asociativní kontejneru třídy, který stejně jako std::unordered_map třídy, řídí různé délky pořadí prvků typu std::pair < const klíč, Ty >.Neuspořádané mapy si můžete Představte jako slovník, který lze přidat do dvojice klíče a hodnoty nebo vyhledat hodnotu klíče.Tato třída je užitečné, pokud máte více podprocesů nebo úkoly, které mají souběžně sdílené kontejner přístup, vložte do něj nebo jej aktualizovat.

Následující příklad zobrazuje základní strukturu pomocí concurrent_unordered_map.Následující příklad vloží znak klíče v rozsahu ["a", "i"].Pořadí operací je neurčený, je také neurčeného konečné hodnoty pro každý klíč.Je bezpečné paralelně provádět vložené položky.

// unordered-map-structure.cpp
// compile with: /EHsc
#include <ppl.h>
#include <concurrent_unordered_map.h>
#include <iostream>

using namespace concurrency;
using namespace std;

int wmain() 
{
    //
    // Insert a number of items into the map in parallel.

    concurrent_unordered_map<char, int> map; 

    parallel_for(0, 1000, [&map](int i) {
        char key = 'a' + (i%9); // Geneate a key in the range [a,i].
        int value = i;          // Set the value to i.
        map.insert(make_pair(key, value));
    });

    // Print the elements in the map.
    for_each(begin(map), end(map), [](const pair<char, int>& pr) {
        wcout << L"[" << pr.first << L", " << pr.second << L"] ";
    });
}
/* Sample output:
    [e, 751] [i, 755] [a, 756] [c, 758] [g, 753] [f, 752] [b, 757] [d, 750] [h, 754]
*/

Příklad, který používá concurrent_unordered_map provedení mapy a snížit provoz paralelně naleznete v tématu Jak: provést mapování a snížit operace paralelně.

Dd504906.collapse_all(cs-cz,VS.110).gifRozdíly mezi concurrent_unordered_map a unordered_map

concurrent_unordered_map Třídy podobá unordered_map třídy.Následující body popisují kde concurrent_unordered_map se liší od unordered_map:

  • The erase, bucket, bucket_count, and bucket_size methods are named unsafe_erase, unsafe_bucket, unsafe_bucket_count, and unsafe_bucket_size, respectively.unsafe_ Konvence označuje, že tyto metody nejsou bezpečné souběžnosti.Další informace o bezpečnosti souběžnosti viz Souběžnosti bezpečné operace.

  • Operace vkládání nečiní stávající ukazatele nebo u iterátorů ani změnit jejich pořadí položek, které již existují v mapě.Vložit a křížovou operací může probíhat souběžně.

  • concurrent_unordered_mappodporuje předávat pouze iteraci.

  • Vložení neruší nebo aktualizovat u iterátorů, které jsou vráceny equal_range.Kurzor můžete připojit neshodných položek na konec rozsahu.Iterační počáteční body stejnou položku.

A zabránit zablokování žádná metoda concurrent_unordered_map při přidělování paměti, funkce hash nebo uživatelem definovaný kód volá drží zámek.Musí také zajistit funkci hash vyhodnocuje vždy stejné klíče na stejnou hodnotu.Nejlepší funkce hash klíče distribuovat rovnoměrně přes prostor kód hash.

Dd504906.collapse_all(cs-cz,VS.110).gifSouběžnost bezpečné operace

concurrent_unordered_map Třídy umožňuje bezpečné souběžnosti operace Vložit a prvek přístup.Vložit operace nečiní stávající ukazatele nebo u iterátorů.Iterační přístup a křížovou kontrolu operace jsou také bezpečné souběžnosti.Následující tabulka obsahuje běžně používané concurrent_unordered_map metody a operátory, které jsou bezpečné souběžnosti.

na

count

find

key_eq

begin

empty

get_allocator

max_size

cbegin

end

hash_function

operátor]

cend

equal_range

Vložit

size

Přestože count metodu lze volat bez obav z současně spuštěné podprocesy, různých podprocesů můžete zobrazit různé výsledky současně vložili nové hodnoty do kontejneru.

Následující tabulka obsahuje běžně používané metody a subjekty, které nejsou bezpečné souběžnosti.

clear

max_load_factor

rehash

load_factor

operátor =

Zaměnit

Vedle těchto metod jakoukoli metodu, začíná unsafe_ není bezpečné souběžnosti.

Top

Třída concurrent_unordered_multimap

Concurrency::concurrent_unordered_multimap třídy podobá concurrent_unordered_map třídy s výjimkou, že umožňuje mapovat na stejný klíč více hodnot.Také odlišuje od concurrent_unordered_map následujícími způsoby:

Následující příklad zobrazuje základní strukturu pomocí concurrent_unordered_multimap.Následující příklad vloží znak klíče v rozsahu ["a", "i"].concurrent_unordered_multimapumožňuje klíč má více hodnot.

// unordered-multimap-structure.cpp
// compile with: /EHsc
#include <ppl.h>
#include <concurrent_unordered_map.h>
#include <iostream>

using namespace concurrency;
using namespace std;

int wmain() 
{
    //
    // Insert a number of items into the map in parallel.

    concurrent_unordered_multimap<char, int> map; 

    parallel_for(0, 10, [&map](int i) {
        char key = 'a' + (i%9); // Geneate a key in the range [a,i].
        int value = i;          // Set the value to i.
        map.insert(make_pair(key, value));
    });

    // Print the elements in the map.
    for_each(begin(map), end(map), [](const pair<char, int>& pr) {
        wcout << L"[" << pr.first << L", " << pr.second << L"] ";
    });
}
/* Sample output:
    [e, 4] [i, 8] [a, 9] [a, 0] [c, 2] [g, 6] [f, 5] [b, 1] [d, 3] [h, 7]
*/

Top

Třída concurrent_unordered_set

Concurrency::concurrent_unordered_set třídy podobá concurrent_unordered_map třídy, která spravuje hodnot namísto dvojice klíče a hodnoty.concurrent_unordered_set Třídy neposkytuje operator[] ani at metoda.

Následující příklad zobrazuje základní strukturu pomocí concurrent_unordered_set.Následující příklad vloží znak hodnoty v rozsahu ["a", "i"].Je bezpečné paralelně provádět vložené položky.

// unordered-set-structure.cpp
// compile with: /EHsc
#include <ppl.h>
#include <concurrent_unordered_set.h>
#include <iostream>

using namespace concurrency;
using namespace std;

int wmain() 
{
    //
    // Insert a number of items into the set in parallel.

    concurrent_unordered_set<char> set; 

    parallel_for(0, 10000, [&set](int i) {
        set.insert('a' + (i%9)); // Geneate a value in the range [a,i].
    });

    // Print the elements in the set.
    for_each(begin(set), end(set), [](char c) {
        wcout << L"[" << c << L"] ";
    });
}
/* Sample output:
    [e] [i] [a] [c] [g] [f] [b] [d] [h]
*/

Top

Třída concurrent_unordered_multiset

Concurrency::concurrent_unordered_multiset třídy podobá concurrent_unordered_set třídy s výjimkou, že umožňuje duplicitní hodnoty.Také odlišuje od concurrent_unordered_set následujícími způsoby:

Následující příklad zobrazuje základní strukturu pomocí concurrent_unordered_multiset.Následující příklad vloží znak hodnoty v rozsahu ["a", "i"].concurrent_unordered_multisetumožňuje hodnotu vyskytnout vícekrát.

// unordered-set-structure.cpp
// compile with: /EHsc
#include <ppl.h>
#include <concurrent_unordered_set.h>
#include <iostream>

using namespace concurrency;
using namespace std;

int wmain() 
{
    //
    // Insert a number of items into the set in parallel.

    concurrent_unordered_multiset<char> set; 

    parallel_for(0, 40, [&set](int i) {
        set.insert('a' + (i%9)); // Geneate a value in the range [a,i].
    });

    // Print the elements in the set.
    for_each(begin(set), end(set), [](char c) {
        wcout << L"[" << c << L"] ";
    });
}
/* Sample output:
    [e] [e] [e] [e] [i] [i] [i] [i] [a] [a] [a] [a] [a] [c] [c] [c] [c] [c] [g] [g]
    [g] [g] [f] [f] [f] [f] [b] [b] [b] [b] [b] [d] [d] [d] [d] [d] [h] [h] [h] [h]
*/

Top

Třída combinable

Concurrency::combinable třída poskytuje opakovaně, podproces místní úložiště, která umožňuje provádět výpočty uzamykání a tyto výpočty sloučit konečný výsledek.Si lze představit combinable objektu jako proměnná snížení.

combinable Třídy je užitečné, pokud máte prostředek, který je sdílen několika podprocesů nebo úkoly.combinable Třídy pomáhá eliminovat poskytnutím přístupu ke sdíleným prostředkům způsobem uvolnit uzamčení sdíleného stavu.Proto tato třída poskytuje alternativu k použití mechanismu synchronizace, například objekt mutex pro synchronizaci přístupu ke sdíleným datům z více podprocesů.

Dd504906.collapse_all(cs-cz,VS.110).gifMetody a funkce

Následující tabulka uvádí některé důležité metod combinable třídy.Další informace o všech combinable metody třídy, viz Třída combinable.

Metoda

Description

místní

Získá referenci na místní proměnnou, která je spojena s aktuální kontext podprocesu.

Vymazat

Odebere všechny podproces místní proměnné z combinable objektu.

kombinovat

combine_each

Funkce poskytované kombinovat generovat konečné hodnoty ze sady všechny výpočty místní podprocesu.

combinable Je šablony třídy, která je na konečný výsledek sloučené Parametrizovaná třída.Pokud volání výchozí konstruktor _Ty typ parametru šablony musí mít výchozí konstruktor a Kopírovat konstruktor.Pokud _Ty typ parametru šablony nemá výchozí konstruktor, přetížené verze konstruktor, který bere jako svůj parametr inicializační funkce volání.

Další data lze uložit combinable objektu po volání kombinovat nebo combine_each metody.Můžete také zavolat combine a combine_each metody vícekrát.Pokud žádné místní hodnota v combinable změny objektu combine a combine_each metody vytvoří stejné výsledky pokaždé, když se nazývají.

Dd504906.collapse_all(cs-cz,VS.110).gifPříklady

Příklady, jak používat combinable třídy, naleznete v následujících tématech:

Top

Příbuzná témata

Odkaz

Třída concurrent_vector

Třída concurrent_queue

Třída concurrent_unordered_map

Třída concurrent_unordered_multimap

Třída concurrent_unordered_set

Třída concurrent_unordered_multiset

Třída combinable