Skip to content
Latchkey

O que é uma Coroutine? Funções que pausam e retomam

Uma coroutine é uma função que pode pausar no meio do caminho, devolver o controle ao seu chamador e mais tarde retomar exatamente de onde parou, mantendo seu estado local.

Funções comuns rodam até o fim uma vez chamadas. Uma coroutine pode suspender no meio, ceder o controle e ser retomada depois com suas variáveis intactas. Esse modelo cooperativo é a base para concorrência leve em linguagens como Go, Kotlin e Python, deixando uma thread fazer malabarismo com milhares de coroutines de forma muito mais barata do que milhares de threads de OS.

Como coroutines diferem de funções

Uma função normal tem uma entrada e uma saída. Uma coroutine tem múltiplos pontos de suspensão: ela pode ceder, preservando seu stack e locais, e ser retomada depois. O controle passa cooperativamente em vez de ser preemptado pelo scheduler do OS.

Coroutines vs threads

Threads são escalonadas preemptivamente pelo OS e são relativamente pesadas. Coroutines são escalonadas cooperativamente em user space e são extremamente leves, então você pode rodar números enormes delas. O trade-off: uma coroutine que nunca cede pode deixar as outras em starvation.

O que coroutines habilitam

  • Concorrência massiva, como uma goroutine por conexão.
  • I/O assíncrono escrito em um estilo limpo e sequencial.
  • Generators que produzem valores preguiçosamente, um de cada vez.
  • Multitarefa cooperativa sem o custo de threads de OS.

Escalonamento cooperativo

Como coroutines cedem voluntariamente, elas só trocam em pontos definidos (como um await ou uma operação de channel). Isso torna raciocinar sobre estado compartilhado mais fácil do que com threads preemptivas, mas uma coroutine que bloqueia sem ceder pode travar tudo em seu scheduler.

Um exemplo rápido

Em Go, iniciar go handle(conn) lança uma goroutine, uma coroutine que o runtime multiplexa em um pequeno pool de threads de OS, então milhares de conexões custam muito pouco.

Coroutines no CI

Código de teste baseado em coroutines pode travar se uma coroutine dá await em algo que nunca completa, estagnando a suíte até o timeout. A Latchkey impõe timeouts de job para que uma coroutine presa não queime minutos indefinidamente, e dá retry apenas em falhas que parecem genuinamente transitórias.

Principais conclusões

  • Uma coroutine pode suspender e retomar, mantendo seu estado local através da pausa.
  • Coroutines são leves e escalonadas cooperativamente, ao contrário das threads preemptivas do OS.
  • Elas habilitam concorrência massiva e barata, mas podem travar um scheduler se nunca cederem.

Guias relacionados