Por que devo usar std::async?

estou a tentar explorar todas as opções da nova norma C++11 em profundidade, ao usar o std:: async e ao ler a sua definição, notei duas coisas, pelo menos no linux com o gcc 4.8.1:

  • chama - assíncrono, mas ele foi realmente um "sequencial de comportamento", que é basicamente na linha onde você chamar o futuro associada a sua função async foo, o programa bloqueia até a execução de foo é concluída.
  • depende do exactamente a mesma biblioteca externa que as outras, e melhores, soluções não-bloqueantes, o que significa pthread, se quiser usar std::async, necessita de pthread.
Neste momento, é natural para mim perguntar Por Que escolher std: async em vez de um simples conjunto de functores ? É uma solução que nem escala em tudo, quanto mais futuro você chamar, menos sensível seu programa será.

Está a escapar-me alguma coisa ? Você pode mostrar um exemplo que é concedido para ser executado em um async, não Bloqueio, Forma ?

Author: Rakete1111, 2013-07-31

4 answers

Se precisar do resultado de uma operação assíncrona, então tem para bloquear, independentemente da biblioteca que use. A idéia é que você pode escolher quando bloquear, e, espero que quando você faz isso, você bloqueia por um tempo insignificante, porque todo o trabalho já foi feito.

Note também que std::async pode ser lançado com políticas std::launch::async ou std::launch::deferred. Se você não especificar, a implementação é permitida a escolher, e pode muito bem optar por usar avaliação diferida, que resultaria em todo o trabalho sendo feito quando você tenta obter o resultado do futuro, resultando em um bloco Mais Longo. Então, se você quiser ter certeza de que o trabalho é feito assíncronamente, use std::launch::async.

 48
Author: juanchopanza, 2013-07-31 06:36:29
    Chama-se async, mas tem um"comportamento sequencial".

Não, se você usar a política std::launch::async então ela funciona assíncronamente em um novo tópico. Se você não especificar uma política que pode executar em um novo tópico.

Basicamente na linha onde você chama o futuro associado com a sua função async foo, o programa bloqueia até que a execução do foo esteja concluída.

Só bloqueia se o foo não tiver terminado., mas se ele foi executado assíncronamente (por exemplo, porque você usa a política std::launch::async) ele pode ter concluído antes de você precisar dele.
  • depende da mesma biblioteca externa que as outras, e melhores, soluções não-bloqueantes, o que significa ptharad, se você quiser usar std::async você precisa pthar.
([11]}errado, ele não tem que ser implementado usando Pthreads (e no Windows não é, ele usa os recursos do ConcRT.)
Neste momento, é natural para mim. perguntando Por Que escolher std:: async sobre até mesmo um conjunto simples de functores ?
Porque garante a segurança dos fios e propaga excepções através dos fios. Pode fazer isso com um simples conjunto de functores?
É uma solução que nem sequer tem escala, quanto mais futuro chamares, menos sensível será o teu programa.
Não necessariamente. Se você não especificar a Política de lançamento, então uma implementação inteligente pode decidir se iniciar um novo tópico, ou retornar uma função diferida, ou retornar algo que decida mais tarde, quando mais recursos podem estar disponíveis. Agora, é verdade que com a implementação do GCC, se você não fornecer uma política de lançamento, então com os lançamentos atuais, ele nunca irá correr em um novo tópico (há um relatório bugzilla para isso) mas isso é uma propriedade dessa implementação, não destd::async em geral. Você não deve confundir a especificação na norma com uma implementação particular. Leitura a implementação de uma biblioteca padrão é uma maneira pobre de aprender sobre C++11.

Você pode mostrar um exemplo que é concedido para ser executado em um async, não bloqueio, caminho ?

Isto não deve bloquear.
auto fut = std::async(std::launch::async, doSomethingThatTakesTenSeconds);
auto result1 = doSomethingThatTakesTwentySeconds();
auto result2 = fut.get();
Ao especificar a Política de lançamento, forçará a execução assíncrona, e se fizer outro trabalho enquanto estiver a ser executado, o resultado estará pronto quando precisar.
 66
Author: Jonathan Wakely, 2014-02-17 03:59:41
Acho que o teu problema é dizeres que bloqueia. Só bloqueia Se o resultado ainda não estiver pronto. Se conseguir que o resultado esteja pronto, não há problema. Há muitas maneiras de saber que o resultado já está pronto. Você pode pesquisar o future e perguntar (relativamente simples), você poderia usar bloqueios ou dados atômicos para transmitir o fato de que ele está pronto, você poderia construir uma estrutura para entregar "finished" future itens em uma fila que os consumidores podem interagir com, você pode usar sinais de algum tipo (que está apenas bloqueando em várias coisas ao mesmo tempo, ou votação). Ou, você pode terminar todo o trabalho que pode fazer localmente, e depois bloquear o trabalho remoto.

Como exemplo, imagine um tipo de junção recursiva paralela. Ele divide o array em dois pedaços, então faz um async ordenar em um pedaço enquanto separa o outro pedaço. Uma vez terminada a triagem da sua metade, o fio originário não pode progresso até que a segunda tarefa esteja concluída. Então faz um bloqueio. Uma vez que ambas as metades foram ordenadas, ele pode então fazer uma junção (em teoria, a junção pode ser feita pelo menos parcialmente em paralelo também).

Esta Tarefa comporta-se como uma tarefa linear para aqueles que interagem com ela no exterior -- quando é feita, a matriz é ordenada.

Podemos então embrulhar isto numa tarefa std::async, e ter uma matriz future ordenada. Se quisermos, podemos acrescentar um procedimento Signal para nos informar que: o future está acabado, mas isso só faz sentido se tivermos um fio à espera dos sinais.

 11
Author: Yakk - Adam Nevraumont, 2013-07-31 14:13:08

Na referência : http://en.cppreference.com/w/cpp/thread/async

Se a bandeira async estiver definida (isto é, política & std::: lançamento:: async != 0), então o async executa a função f num tópico separado de execução como se spawned by std:: thread (f, args...), excepto que Se a função f retorna um valor ou lança uma exceção, ele é armazenado no compartilhado estado acessível através do std:: futuro que async retorna ao ouvinte.

É uma boa propriedade manter um registo de excepções.
 3
Author: fatihk, 2013-07-31 06:38:20