Paralelo recipientes e objetos

O paralela padrões PPL (biblioteca) inclui vários recipientes e objetos que fornecem acesso de thread-safe para seus elementos.

A simultânea recipiente fornece a prova de simultaneidade acesso às operações mais importantes. A funcionalidade desses recipientes se parece com aqueles que são fornecidos pelo modelo Biblioteca STL (Standard). Por exemplo, o Concurrency::concurrent_vector classe semelhante a std:: Vector de classe, exceto que o concurrent_vector classe permite acrescentar elementos em paralelo. Use os recipientes simultâneas quando tiver código paralelo que requer acesso de leitura e gravação ao mesmo recipiente.

A objeto simultâneo é compartilhada simultaneamente entre componentes. Um processo que computa o estado de um objeto simultâneo em paralelo produz o mesmo resultado que outro processo que calcula o mesmo estado em série. O Concurrency::combinable classe é um exemplo de um tipo de objeto simultâneas. O combinable classe permite executar cálculos em paralelo e combine esses cálculos em um resultado final. Quando você usaria um mecanismo de sincronização, por exemplo, um mutex para sincronizar o acesso a uma variável compartilhada ou um recurso, use objetos simultâneos.

Seções

Este tópico descreve os seguintes recipientes paralelas e objetos em detalhes.

Recipientes simultâneas:

  • concurrent_vector classe

  • concurrent_queue classe

Objetos simultâneos:

  • Classe podem ser combinada

concurrent_vector classe

O Concurrency::concurrent_vector é uma classe de contêiner de seqüência que, assim como o std:: Vector da classe, que permite que você acesse aleatoriamente os seus elementos. O concurrent_vector classe permite a prova de simultaneidade acrescentar e operações de acesso do elemento. Acrescentar operações invalida ponteiros existentes ou iteradores. Operações de acesso e a passagem do iterador também são prova de simultaneidade.

Diferenças entre concurrent_vector e vetor

O concurrent_vector classe parecida com o vector classe. A complexidade de acrescentar, acesso ao elemento e operações de acesso do iterador em uma concurrent_vector objeto são as mesmas para um vector objeto. Os pontos a seguir ilustram onde concurrent_vector difere do vector:

  • Acrescentar, acesso ao elemento, acesso de iterador e operações de travessia do iterador em uma concurrent_vector objeto são simultaneidade-safe.

  • Você pode adicionar elementos somente ao final de uma concurrent_vector objeto. O concurrent_vector classe não oferece o insert método.

  • A concurrent_vector não usa o objeto move a semântica quando você anexar a ele.

  • O concurrent_vector classe não oferece o erase ou pop_back métodos. Como com vector, use o Limpar método para remover todos os elementos de um concurrent_vector objeto.

  • O concurrent_vector classe não armazena seus elementos contiguamente na memória. Portanto, não é possível usar o concurrent_vector a classe de todas as maneiras que você pode usar uma matriz. Por exemplo, para uma variável chamada v do tipo concurrent_vector, a expressão &v[0]+2 produz comportamento indefinido.

  • O concurrent_vector classe define o grow_by e grow_to_at_least métodos. Esses métodos se parecem com o Redimensionar método, exceto que eles são seguros de simultaneidade.

  • A concurrent_vector objeto não realocar seus elementos quando você anexar a ele ou redimensionar o proprietário. Isso permite que os ponteiros existentes e iteradores permaneça válida durante operações simultâneas.

  • O runtime não define uma versão especializada do concurrent_vector para o tipo de bool.

Operações com segurança de simultaneidade

Todos os métodos que acrescentar ou aumentam o tamanho de um concurrent_vector object ou acessar um elemento em um concurrent_vector de objeto, são de simultaneidade-safe. A exceção a essa regra é o resize método.

A tabela a seguir mostra a common concurrent_vector métodos e os operadores que fazem a simultaneidade-safe.

em

final

operador]

começar

frente

push_back

Voltar

grow_by

rbegin

capacidade

grow_to_at_least

rend

vazio

max_size

tamanho

Operações que o runtime fornece compatibilidade com STL, por exemplo, reserve, não são simultaneidade-safe. A tabela a seguir mostra os métodos de comuns e os operadores não são à prova de simultaneidade.

atribuir

reservar

Limpar

redimensionar

operador =

shrink_to_fit

Operações de modificar o valor de elementos existentes não são seguros de simultaneidade. Usar um objeto de sincronização, como um reader_writer_lock o objeto para sincronizar a leitura simultânea e operações de gravação para o mesmo elemento de dados. Para obter mais informações sobre objetos de sincronização, consulte Estruturas de dados de sincronização.

Quando você converte o código existente que usa vector para usar concurrent_vector, operações simultâneas podem causar o comportamento do seu aplicativo para alterar. Por exemplo, considere o seguinte programa que executa simultaneamente a duas tarefas em um concurrent_vector objeto. A primeira tarefa acrescenta elementos adicionais para um concurrent_vector objeto. A segunda tarefa calcula a soma de todos os elementos no mesmo objeto.

// 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 = v.begin(); i != v.end(); ++i) 
         {
            sums.local() += *i;
         }     
         wcout << L"sum = " << sums.combine(plus<int>()) << endl;
      }
   );
}

Embora o end método é seguro de simultaneidade, uma chamada simultânea para o push_back método faz com que o valor retornado por end a alteração. O número de elementos que percorre o iterador é indeterminado. Portanto, este programa pode produzir um resultado diferente cada vez que executá-lo.

Segurança de exceção

Se uma operação de crescimento ou atribuição lança uma exceção, o estado do concurrent_vector o objeto se torna inválida. O comportamento de um concurrent_vector o objeto que está em um estado inválido é indefinido, salvo indicação em contrário. No entanto, o destruidor sempre libera a memória que o objeto aloca, mesmo se o objeto está em um estado inválido.

O tipo de dados de elementos de vetor, _Ty, deve atender aos seguintes requisitos. Caso contrário, o comportamento da concurrent_vector classe é indefinido.

  • O destruidor não deve lançar.

  • Se o construtor padrão ou cópia lança, o destruidor não deve ser declarado usando a virtual palavra-chave e ele devem funcionar corretamente com memória inicializada para zero.

go to top

concurrent_queue classe

O Concurrency::concurrent_queue de classe, como o std::queue da classe, que permite acessar a sua frente e elementos de volta. O concurrent_queue classe permite que a concorrência segura enqueue e dequeue operações. O concurrent_queue classe também fornece suporte de iterador não é simultaneidade-safe.

Fila e diferenças entre o concurrent_queue

O concurrent_queue classe parecida com o queue classe. Os pontos a seguir ilustram onde concurrent_queue difere do queue:

  • Enqueue e dequeue operações em um concurrent_queue objeto são simultaneidade-safe.

  • O concurrent_queue classe fornece suporte de iterador não é simultaneidade-safe.

  • O concurrent_queue classe não oferece o front ou pop métodos. O concurrent_queue classe substitui esses métodos, definindo a try_pop método.

  • O concurrent_queue classe não oferece o back método. Portanto, você não pode referenciar o final da fila.

  • O concurrent_queue classe fornece o unsafe_size método em vez da size método. O unsafe_size o método não é a simultaneidade-safe.

Operações com segurança de simultaneidade

Todos os métodos que enqueue para ou retirar a partir de um concurrent_queue objeto são simultaneidade-safe.

A tabela a seguir mostra a common concurrent_queue métodos e os operadores que fazem a simultaneidade-safe.

vazio

envio

get_allocator

try_pop

Embora o empty método é seguro de simultaneidade, uma operação simultânea pode fazer com que a fila aumente ou diminua antes de empty método retorna.

A tabela a seguir mostra os métodos de comuns e os operadores não são à prova de simultaneidade.

Limpar

unsafe_end

unsafe_begin

unsafe_size

Suporte de iterador

O concurrent_queue fornece os iteradores que não são simultaneidade-safe. Recomendamos que você use esses iteradores para depuração somente.

A concurrent_queue iterador percorre os elementos na direção progressiva. A tabela a seguir mostra os operadores que oferece suporte a cada iterador.

Operador

Descrição

operador + +

Avança para o próximo item na fila. Este operador está sobrecarregado para fornecer a semântica de pre-increment e post-increment.

operador *

Recupera uma referência ao item atual.

operador - >

Recupera um ponteiro para o item atual.

go to top

Classe podem ser combinada

O Concurrency::combinable classe fornece armazenamento reutilizável, local de segmento que permite realizar cálculos refinados e mesclar essas computações um resultado final. Você pode pensar em um combinable o objeto como uma variável de redução.

O combinable classe é útil quando você tem um recurso que é compartilhado entre vários threads ou tarefas. O combinable compartilhado de ajuda de classe, eliminar o estado compartilhado, fornecendo acesso a recursos em uma forma sem bloqueio. Portanto, essa classe fornece uma alternativa ao uso de um mecanismo de sincronização, por exemplo, um mutex para sincronizar o acesso aos dados compartilhados de vários threads.

Métodos e recursos

A tabela a seguir mostra alguns dos métodos de importantes a combinable classe. Para obter mais informações sobre todos os combinable métodos de classe, consulte Classe podem ser combinada.

Método

Descrição

local

Recupera uma referência para a variável local que está associada com o contexto do thread atual.

Limpar

Remove todas as variáveis de segmento local da combinable objeto.

combinar

combine_each

Utiliza a função de combinar fornecido para gerar um valor final do conjunto de todos os cálculos de segmento local.

O combinable é uma classe de modelo que é parametrizada sobre o resultado final mesclado. Se você chamar o construtor padrão, o _Ty o tipo de parâmetro de modelo deve ter um construtor padrão e um construtor de cópia. Se o _Ty tipo de parâmetro de modelo não tem um construtor padrão, chame a versão sobrecarregada do construtor que leva a uma função de inicialização como parâmetro.

Você pode armazenar dados adicionais em um combinable objeto depois de chamar o combinar ou combine_each métodos. Você também pode chamar o combine e combine_each métodos várias vezes. Se nenhum valor local em um combinable objeto alterações, o combine e combine_each métodos produzir o mesmo resultado toda vez que eles são chamados.

Exemplos

Para obter exemplos sobre como usar o combinable da classe, consulte os seguintes tópicos:

go to top

Tópicos relacionados

Referência

concurrent_vector classe

concurrent_queue classe

Classe podem ser combinada