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 usarstd::async
, necessita de pthread.
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
.
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.
Só bloqueia se o foo não tiver terminado., mas se ele foi executado assíncronamente (por exemplo, porque você usa a políticaBasicamente 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.
std::launch::async
) ele pode ter concluído antes de você precisar dele.
([11]}errado, ele não tem que ser implementado usando Pthreads (e no Windows não é, ele usa os recursos do ConcRT.)
- 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.
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 de
std::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.
Isto não deve bloquear.Você pode mostrar um exemplo que é concedido para ser executado em um async, não bloqueio, caminho ?
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.
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.
Na referência : http://en.cppreference.com/w/cpp/thread/async
É uma boa propriedade manter um registo de excepções.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.