Programação Assíncrona em C++: guia completo na prática

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Programação Assíncrona em C++: guia completo na prática

Programação assíncrona em C++ é uma abordagem que permite executar várias tarefas em paralelo, sem bloquear o fluxo principal de execução. Ao contrário do código síncrono, onde cada operação aguarda a conclusão da anterior, o código assíncrono pode iniciar operações longas (entrada/saída, requisições de rede, cálculos) e continuar executando outras tarefas enquanto essas operações são concluídas em segundo plano. Isso é fundamental para criar aplicações responsivas, especialmente na indústria de jogos, servidores web e sistemas de tempo real.

Neste artigo, abordaremos a programação assíncrona em C++ na prática: desde os mecanismos clássicos std::async e std::future até as modernas corrotinas C++20. Você aprenderá como usar essas ferramentas corretamente, evitar erros comuns e criar sistemas assíncronos eficientes.



1. Fundamentos da assincronia: std::async e std::future

A biblioteca padrão C++11 fornece uma maneira simples de iniciar tarefas assíncronas — a função std::async e a classe std::future. std::async inicia uma função em uma thread separada (ou pool de threads) e retorna um std::future, que contém o resultado da execução.



Exemplo 1: Inicialização básica de uma tarefa assíncrona

#include <iostream>#include <future>#include <thread>#include <chrono>

int longComputation(int n) { std::this_thread::sleep_for(std::chrono::seconds(2)); return n * n;}

int main() { std::cout << "Iniciando tarefa assíncrona..." << std::endl; std::future<int> result = std::async(std::launch::async, longComputation, 10);

// Enquanto a tarefa é executada, pode-se fazer outro trabalho std::cout << "Thread principal continua trabalhando..." << std::endl; std::this_thread::sleep_for(std::chrono::seconds(1));

// Obtendo o resultado (bloqueia a thread se a tarefa ainda não foi concluída) int value = result.get(); std::cout << "Resultado: " << value << std::endl; return 0;}


Pontos importantes:

  • std::launch::async garante a execução em uma thread separada.
  • result.get() bloqueia a thread atual até obter o resultado.
  • Se get() não for chamado, o destrutor de std::future pode bloquear a execução até a conclusão da tarefa.


Exemplo 2: Tratamento de exceções em tarefas assíncronas

#include <iostream>#include <future>#include <stdexcept>

int riskyFunction(int x) { if (x < 0) throw std::runtime_error("Número negativo!"); return x * 2;}

int main() { std::future<int> future = std::async(std::launch::async, riskyFunction, -5); try { int result = future.get(); std::cout << "Resultado: " << result << std::endl; } catch (const std::exception& e) { std::cout << "Exceção: " << e.what() << std::endl; } return 0;}


2. Trabalho avançado com std::future e std::promise

std::promise é uma ferramenta para gerenciamento manual de resultados assíncronos. Você pode definir um valor ou exceção em uma thread e obtê-lo através de std::future em outra. Isso é útil para implementar padrões assíncronos personalizados, como transferência de dados entre threads.



Exemplo 3: Uso de std::promise para transferência de dados

#include <iostream>#include <future>#include <thread>

void producer(std::promise<std::string> prom) { std::this_thread::sleep_for(std::chrono::seconds(1)); prom.set_value("Dados prontos!");}

int main() { std::promise<std::string> promise; std::future<s

Blogs

Book Recommendations