Udostępnij za pośrednictwem


Równoległe kontenerów i obiektów

Biblioteka desenie równoległe (PPL) obejmuje kilka kontenerów i obiektów, wielowątkowość dostępu do ich elementów.

A równoczesne kontenera zapewnia współbieżność bezpieczny dostęp do najważniejszych operacji.Funkcje tych pojemników podobne do tych, które są dostarczane przez standardowe biblioteki szablonu (STL).Na przykład concurrency::concurrent_vector podobny do klasy std::vector klasy, z wyjątkiem concurrent_vector klasy umożliwia dołączanie elementów jednocześnie.Przy jednoczesnych kontenerów równoległych kod, który wymaga zarówno odczytu i zapisu do tego samego pojemnika.

A równoczesnych obiektu współużytkowany równocześnie składników.Proces, który oblicza stan równoczesnych obiektu równolegle daje taki sam wynik jak inny proces, który oblicza seryjnie tym samym stanie.Concurrency::combinable klasy jest przykładem tego typu obiektu równoczesnych.combinable Klasy umożliwia wykonywanie obliczeń równolegle, a następnie połączenie tych obliczeń w wyniku końcowego.Przy jednoczesnych obiektów do synchronizowania dostępu do udostępnionych zmiennej lub zasobu w przeciwnym razie korzystałyby mechanizm synchronizacji, na przykład mutex.

Sekcje

W tym temacie opisano następujące pojemniki równoległych i obiekty szczegółowo.

Równoczesne kontenery:

  • Klasa concurrent_vector

    • Różnice między concurrent_vector i wektorowe

    • Operacje bezpiecznego współbieżności

    • Wyjątek bezpieczeństwa

  • Klasa concurrent_queue

    • Różnice między concurrent_queue i kolejki

    • Operacje bezpiecznego współbieżności

    • Obsługa iteratora

  • Klasa concurrent_unordered_map

    • Różnice między concurrent_unordered_map i unordered_map

    • Operacje bezpiecznego współbieżności

  • Klasa concurrent_unordered_multimap

  • Klasa concurrent_unordered_set

  • Klasa concurrent_unordered_multiset

Równoczesne obiektów:

  • Klasa łączonymi

    • Metody i funkcje

    • Przykłady

Klasa concurrent_vector

Concurrency::concurrent_vector klasa jest klasą sekwencji kontenera, który, podobnie jak std::vector klasy, umożliwia dostęp losowo jego elementów.concurrent_vector Klasy pozwala dołączyć współbieżności bezpieczny i element dostęp.Dołącz operacji nie unieważnia istniejące wskaźniki lub Iteratory.Operacje dostępu i przechodzenie iteratora są również bezpieczne współbieżności.

Dd504906.collapse_all(pl-pl,VS.110).gifRóżnice między concurrent_vector i wektorowe

concurrent_vector Przypominającym klasę vector klasy.Złożoność dołączającej, dostęp do elementu i iteratora operacje dostępu na concurrent_vector obiektu są takie same, jak w przypadku vector obiektu.Punkty ilustrują where concurrent_vector różni się od vector:

  • Dołącz dostępu do elementu, iteratora dostępu i iteratora przechodzenia operacji na concurrent_vector obiektu są bezpieczne współbieżności.

  • Elementy można dodać tylko do końca concurrent_vector obiektu.concurrent_vector Klasy nie dostarcza insert metody.

  • A concurrent_vector obiektu nie korzysta z przenieść semantykę podczas dołączania do niego.

  • concurrent_vector Klasy nie dostarcza erase lub pop_back metody.Tak jak w vector, użyj Wyczyść metodę, aby usunąć wszystkie elementy z concurrent_vector obiektu.

  • concurrent_vector Klasy nie przechowuje jego elementy ciągły obszar w pamięci.Dlatego nie można używać concurrent_vector klasy wszystkie sposoby używania tablicy.Na przykład dla zmiennej o nazwie v typu concurrent_vector, wyrażenie &v[0]+2 powoduje zachowanie niezdefiniowany.

  • concurrent_vector w klasie grow_by i grow_to_at_least metody.Metody te przypominają zmienić rozmiar metodę, z wyjątkiem, że są one bezpieczne współbieżności.

  • A concurrent_vector podczas dołączania do niego lub zmienić jego rozmiar, obiekt nie przenieść jego elementów.Umożliwia to istniejące wskaźniki i Iteratory pozostaje ważne podczas operacji jednoczesnych.

  • Środowiska wykonawczego nie definiuje wersji wyspecjalizowanych concurrent_vector dla typu bool.

Dd504906.collapse_all(pl-pl,VS.110).gifOperacje bezpiecznego współbieżności

Wszystkie metody, które są dołączone do lub zwiększyć rozmiar concurrent_vector obiektu lub dostępu do elementu w concurrent_vector obiektów, są bezpieczne współbieżności.Wyjątkiem od tej reguły jest resize metody.

W poniższej tabeli przedstawiono wspólnej concurrent_vector metody i podmioty gospodarcze, które są bezpieczne współbieżności.

na

koniec

operatora]

Rozpocznij

przednie

push_back

Wstecz

grow_by

rbegin

pojemność

grow_to_at_least

rend

pusty

max_size

rozmiar

Operacje, które środowisko wykonawcze zapewnia zgodność z STL, na przykład, reserve, nie są bezpieczne współbieżności.W poniższej tabeli przedstawiono wspólnych metod i podmioty gospodarcze, które nie są bezpieczne współbieżności.

Przypisywanie

rezerwy

Wyczyść

Zmienianie rozmiaru

operator =

shrink_to_fit

Operacje, które należy zmodyfikować wartość istniejące elementy nie są bezpieczne współbieżności.Użyj obiektu synchronizacji, takich jak reader_writer_lock obiekt, aby zsynchronizować odczytu jednoczesnych operacji zapisu i do tego samego elementu danych.Aby uzyskać więcej informacji na temat obiektów synchronizacji zobacz Synchronizacja struktury danych.

Podczas konwertowania istniejącego kodu vector , aby użyć concurrent_vector, równoczesne operacje powodują zachowanie aplikacji, aby zmienić.Na przykład, rozważmy następujący program, który jednocześnie wykonuje dwa zadania na concurrent_vector obiektu.Pierwsze zadanie dołącza dodatkowych elementów do concurrent_vector obiektu.Drugie zadanie oblicza sumę wszystkich elementów w tym samym obiekcie.

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

Chociaż end metoda jest bezpieczny współbieżności równoczesne wywołanie push_back metoda powoduje, że wartość zwracaną przez end do zmiany.Liczba elementów, które przechodzi iteratora jest nieokreślony.W związku z tym ten program może spowodować różne wyniki przy każdym uruchomieniu go.

Dd504906.collapse_all(pl-pl,VS.110).gifWyjątek bezpieczeństwa

Jeśli operacja wzrostu lub przypisania zgłasza wyjątek stanu concurrent_vector obiekt staje się nieprawidłowy.Zachowanie concurrent_vector obiekt, który jest w nieprawidłowym stanie jest niezdefiniowana, chyba że stwierdzono inaczej.Jednakże destruktor zawsze zwalnia pamięci przydzielanej przez obiekt, nawet jeśli obiekt jest w nieprawidłowym stanie.

Typ danych elementów wektorów _Ty, muszą spełniać następujące wymagania.W przeciwnym razie zachowanie concurrent_vector klasy jest niezdefiniowane.

  • Nie musisz throw destruktor.

  • Jeśli generuje konstruktora domyślnego lub Kopiuj, destruktor nie muszą być zadeklarowane za pomocą virtual słowa kluczowego i jego musi działać poprawnie z pamięcią zainicjowany przez zero.

Top

Klasa concurrent_queue

Concurrency::concurrent_queue klasy, podobnie jak std::queue klasy, umożliwia dostęp do jego przednich i z powrotem elementy.concurrent_queue Klasy kolejkowania wywołań zwrotnych umożliwia bezpieczne współbieżności i usuwania z kolejki operacji.concurrent_queue Klasy udostępnia również obsługę iteratora, który nie jest bezpieczny współbieżności.

Dd504906.collapse_all(pl-pl,VS.110).gifRóżnice między concurrent_queue i kolejki

concurrent_queue Przypominającym klasę queue klasy.Punkty ilustrują where concurrent_queue różni się od queue:

  • Kolejkowania wywołań zwrotnych i usuwania z kolejki operacji na concurrent_queue obiektu są bezpieczne współbieżności.

  • concurrent_queue Klasy zapewnia obsługę iteratora, który nie jest bezpieczny współbieżności.

  • concurrent_queue Klasy nie dostarcza front lub pop metody.concurrent_queue Klasy zastępuje te metody, definiując try_pop metody.

  • concurrent_queue Klasy nie dostarcza back metody.Dlatego nie można odwoływać się koniec kolejki.

  • concurrent_queue Klasy unsafe_size metoda zamiast size metody.unsafe_size Metoda nie jest bezpieczny współbieżności.

Dd504906.collapse_all(pl-pl,VS.110).gifOperacje bezpiecznego współbieżności

Wszystkie metody tego kolejkowania wywołań zwrotnych do lub usuwania z kolejki z concurrent_queue obiektu są bezpieczne współbieżności.

W poniższej tabeli przedstawiono wspólnej concurrent_queue metody i podmioty gospodarcze, które są bezpieczne współbieżności.

pusty

wypychania

get_allocator

try_pop

Chociaż empty metody bezpiecznego współbieżności, równoczesnych operacji może spowodować kolejki jest powiększany lub zmniejszany przed empty metoda zwraca.

W poniższej tabeli przedstawiono wspólnych metod i podmioty gospodarcze, które nie są bezpieczne współbieżności.

Wyczyść

unsafe_end

unsafe_begin

unsafe_size

Dd504906.collapse_all(pl-pl,VS.110).gifObsługa iteratora

concurrent_queue Zapewnia Iteratory, które nie są bezpieczne współbieżności.Zaleca się, aby użyć tych Iteratory tylko debugowanie.

A concurrent_queue iteratora przechodzi elementów w kierunku do przodu tylko.W poniższej tabeli przedstawiono operatory, że obsługuje każdego iteratora.

Operator

Opis

operator ++

Zaliczki na następny element w kolejce.Ten operator jest przeciążony zapewnienie semantykę zarówno pre-increment, jak i postinkrementacja.

operator *

Pobiera odwołanie do bieżącego elementu.

operator - >

Pobiera wskaźnik do bieżącego elementu.

Top

Klasa concurrent_unordered_map

Concurrency::concurrent_unordered_map klasa jest klasą asocjacyjną kontenera, który, podobnie jak std::unordered_map klasy, kontroluje sekwencji długość różnych elementów typu std::pair < klucz const, Ty >.Nieuporządkowana mapy można traktować jako słownik, który można dodać parę kluczy i wartości do lub wyszukiwanie wartości przez klucz.Ta klasa jest przydatne, gdy kilka wątków lub zadania, które mają jednocześnie dostęp do udostępnionych kontenera, go wstawić lub zaktualizować go.

Poniższy przykład pokazuje podstawową strukturę za pomocą concurrent_unordered_map.W tym przykładzie wstawia klawiszy znaków z zakresu ["," "i"].Kolejność operacji jest nieokreślony, dlatego końcowej dla każdego klucza również jest nieokreślony.Jednakże jest bezpiecznie wykonywać wstawienia równolegle.

// 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]
*/

Na przykład, że korzysta z concurrent_unordered_map do wykonywania mapy i zmniejszyć operacji równolegle, zobacz Jak: wykonywanie mapę i zmniejszyć operacji równolegle.

Dd504906.collapse_all(pl-pl,VS.110).gifRóżnice między concurrent_unordered_map i unordered_map

concurrent_unordered_map Przypominającym klasę unordered_map klasy.Punkty ilustrują where concurrent_unordered_map różni się 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_ Konwencji nazewnictwa wskazuje, że metody te nie są bezpieczne współbieżności.Aby uzyskać więcej informacji na temat bezpieczeństwa współbieżności zobacz Safe współbieżności operacji.

  • Operacje nie unieważnia istniejące wskaźniki lub Iteratory nie należy zmieniać kolejność elementów, które już istnieją w mapie.Wstawianie i przechodzenia operacji może być wykonywane równocześnie.

  • concurrent_unordered_mapobsługuje przesyła tylko iteracji.

  • Wstawiania nie unieważnia lub zaktualizować Iteratory, które są zwracane przez equal_range.Wstawiania można dołączyć nierówne elementy, na końcu zakresu.Punkty iteratora do elementu równego.

W celu uniknięcia zakleszczenia, nie metody concurrent_unordered_map posiada blokadę, gdy wywołuje program przydzielania pamięci, funkcje mieszania lub inny kod zdefiniowany przez użytkownika.Również należy się upewnić, że funkcja mieszania zawsze oblicza klucze równej do tej samej wartości.Najważniejsze funkcje mieszania rozpowszechniania kluczy jednolicie całej przestrzeni mieszania kodu.

Dd504906.collapse_all(pl-pl,VS.110).gifOperacje bezpiecznego współbieżności

concurrent_unordered_map Klasy umożliwia bezpieczne współbieżności Wstaw i element dostępu operacji.Operacje nie unieważnia istniejące wskaźniki lub Iteratory.Operacje dostępu i przechodzenie iteratora są również bezpieczne współbieżności.W poniższej tabeli przedstawiono powszechnie używanych concurrent_unordered_map metody i podmioty gospodarcze, które są bezpieczne współbieżności.

na

count

find

key_eq

begin

empty

get_allocator

max_size

cbegin

end

hash_function

operatora]

cend

equal_range

Wstaw

size

Chociaż count metoda może być bezpiecznie wywoływana jednocześnie uruchamianie wątków, różne wątki mogą odbierać różne wyniki, jeśli jednocześnie dodaje się nową wartość do pojemnika.

W poniższej tabeli przedstawiono najczęściej używanych metod i podmioty gospodarcze, które nie są bezpieczne współbieżności.

clear

max_load_factor

rehash

load_factor

operator =

Zamień

Oprócz tych metod, każda metoda który zaczyna się od unsafe_ również nie jest bezpieczny współbieżności.

Top

Klasa concurrent_unordered_multimap

Concurrency::concurrent_unordered_multimap przypominającym klasę concurrent_unordered_map klasy, z wyjątkiem, że pozwala ona na wiele wartości mapować do tego samego klucza.Również różni się od concurrent_unordered_map w następujący sposób:

Poniższy przykład pokazuje podstawową strukturę za pomocą concurrent_unordered_multimap.W tym przykładzie wstawia klawiszy znaków z zakresu ["," "i"].concurrent_unordered_multimapWłącza klucz wieloma wartościami.

// 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

Klasa concurrent_unordered_set

Concurrency::concurrent_unordered_set przypominającym klasę concurrent_unordered_map klasy, chyba że zarządza wartości zamiast par kluczy i wartości.concurrent_unordered_set Klasy nie dostarcza operator[] ani at metody.

Poniższy przykład pokazuje podstawową strukturę za pomocą concurrent_unordered_set.W tym przykładzie wstawia znak wartości z zakresu ["," "i"].Bezpiecznie wykonywać wstawienia równolegle.

// 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

Klasa concurrent_unordered_multiset

Concurrency::concurrent_unordered_multiset przypominającym klasę concurrent_unordered_set klasy, z wyjątkiem, że pozwala ona na zduplikowane wartości.Również różni się od concurrent_unordered_set w następujący sposób:

Poniższy przykład pokazuje podstawową strukturę za pomocą concurrent_unordered_multiset.W tym przykładzie wstawia znak wartości z zakresu ["," "i"].concurrent_unordered_multisetUmożliwia wartość występuje wiele razy.

// 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

Klasa łączonymi

Concurrency::combinable klasy zapewnia przechowywanie wielokrotnego użytku, lokalnej wątku, który pozwala wykonywać obliczenia szczegółowymi, a następnie scalić tych obliczeniach wyniku końcowego.Można traktować combinable obiektu jako zmienna redukcji.

combinable Klasy jest przydatne, gdy dany zasób współużytkowany kilka wątków lub zadań.combinable Klasy pomaga wyeliminować stan udostępnionego przez zapewnienie dostępu do zasobów udostępnionych w sposób wolny blokady.W związku z tym Klasa ta stanowi alternatywę dla za pomocą mechanizmu synchronizacji, na przykład mutex do synchronizowania dostępu do udostępnionych danych z wielu wątków.

Dd504906.collapse_all(pl-pl,VS.110).gifMetody i funkcje

W poniższej tabeli przedstawiono niektóre z ważnych metod combinable klasy.Aby uzyskać więcej informacji o wszystkich combinable metody klasy, zobacz Klasa łączonymi.

Metoda

Opis

lokalne

Pobiera odwołanie do zmiennej lokalnej, skojarzony z bieżącym kontekstem wątku.

Wyczyść

Usuwa wszystkie zmienne lokalne dla wątku z combinable obiektu.

Łączenie

combine_each

Funkcja Łączenie dostarczonego do generowania wartości końcowej z zestawu obejmującego wszystkie obliczenia lokalnej wątku.

combinable Klasa jest klasą szablonu, która jest parametryzowana na ostateczny wynik scalone.Jeśli wywołanie konstruktora domyślnego _Ty typ parametru szablonu musi mieć konstruktora domyślnego i konstruktora kopii.Jeśli _Ty typ parametru szablonu nie ma domyślnego konstruktora, wywołaj przeciążony wersję konstruktora, który ma funkcję inicjalizacji jako parametr.

Można przechowywać dodatkowe dane w combinable obiektu po wywołaniu połączyć lub combine_each metody.Można również wywołać combine i combine_each metody wiele razy.Jeśli nie lokalne wartość w combinable obiektu zmian, combine i combine_each metody produkcji tego samego rezultatu każdym razem, gdy są one nazywane.

Dd504906.collapse_all(pl-pl,VS.110).gifPrzykłady

Do przykładów na temat używania combinable klasy, zobacz następujące tematy:

Top

Tematy pokrewne

Odwołanie

Klasa concurrent_vector

Klasa concurrent_queue

Klasa concurrent_unordered_map

Klasa concurrent_unordered_multimap

Klasa concurrent_unordered_set

Klasa concurrent_unordered_multiset

Klasa łączonymi