0% acharam este documento útil (0 voto)
6 visualizações28 páginas

Python Vs Rust Async

O documento compara a programação assíncrona em Python e Rust, destacando como cada linguagem lida com I/O concorrente. Em Python, utiliza-se corrotinas e um event loop, enquanto em Rust, funções assíncronas retornam um Future que deve ser pollado por um runtime. A diferença central é que, em Rust, o modelo de async é mais explícito e exige considerações sobre ownership e segurança de memória.
Direitos autorais
© All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
0% acharam este documento útil (0 voto)
6 visualizações28 páginas

Python Vs Rust Async

O documento compara a programação assíncrona em Python e Rust, destacando como cada linguagem lida com I/O concorrente. Em Python, utiliza-se corrotinas e um event loop, enquanto em Rust, funções assíncronas retornam um Future que deve ser pollado por um runtime. A diferença central é que, em Rust, o modelo de async é mais explícito e exige considerações sobre ownership e segurança de memória.
Direitos autorais
© All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd

09/03/2026, 16:45 Python vs Rust Async

Sou programador Python aprendendo Rust, tenha ótima


didática e faça correlação entre as linguagens, mostre
como o rust trabalha com Async

Vou te explicar conectando Python asyncio com Rust async / await , e vou me apoiar na
documentação oficial para não te passar nenhum detalhe torto.

Pensou por 21s

Claro. Vamos fazer do jeito certo: comparando Python com Rust, porque isso acelera
muito o aprendizado.

Visão geral
Em Python, async é principalmente uma forma prática de lidar com I/O concorrente
usando asyncio , corrotinas, tasks e um event loop. O loop executa tarefas e callbacks;
quando uma task encontra await , ela é suspensa e o loop pode rodar outra.
Python docume… +2

Em Rust, a ideia também gira em torno de I/O assíncrona, mas o modelo é mais explícito
e mais baixo nível: uma função async retorna um Future, e esse future só avança quando
é pollado por um runtime/executor. O trait Future da biblioteca padrão define isso com
poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> .
[Link] +2

A correlação mental mais importante


Pensa assim:
Python async def → cria uma corrotina
Rust async fn → cria um valor que implementa Future
Python await → entrega o controle ao event loop
Rust .await → suspende a execução daquele future até ele estar pronto
Python asyncio.create_task() → agenda uma tarefa no loop
Rust tokio::spawn(...) → agenda uma task no runtime Tokio Python docume… +3

1) Exemplo mínimo: Python vs Rust


[Link] 1/28
09/03/2026, 16:45 Python vs Rust Async

Python

import asyncio

async def buscar_dados():


await [Link](1)
return "ok"

async def main():


resultado = await buscar_dados()
print(resultado)

[Link](main())

Aqui acontece:
1. buscar_dados() é uma corrotina.
2. await [Link](1) pausa essa corrotina.
3. O event loop pode rodar outra coisa nesse intervalo.
4. Depois ela volta e retorna "ok" .

A própria documentação oficial do Python descreve asyncio como base para código
concorrente com async/await . Python docume… +1

Rust

async fn buscar_dados() -> String {


tokio::time::sleep(std::time::Duration::from_secs(1)).await;
"ok".to_string()
}

#[tokio::main]
async fn main() {
let resultado = buscar_dados().await;
println!("{}", resultado);
}

Aqui:
1. async fn buscar_dados() não executa imediatamente como função normal.
2. Ela retorna um Future.
3. Quando fazemos .await , o runtime vai dirigindo a execução desse future.
4. tokio::time::sleep(...).await suspende a task sem bloquear a thread do mesmo
jeito “conceitual” que você espera de async. [Link] +2

[Link] 2/28
09/03/2026, 16:45 Python vs Rust Async

2) A grande diferença: em Rust, async é um valor


Essa é a virada de chave.

Em Python
Quando você chama:

coroPython
= buscar_dados()
Executar

você obtém um objeto aguardável/corrotina.

Em Rust
Quando você chama:

let Rust
fut = buscar_dados();

você obtém um future.

A diferença é que em Rust isso é muito central no tipo. O Future é um trait da std, e a
computação assíncrona é representada como um valor que pode estar “pendente” ou
“pronto”. [Link] +1

3) Como o Rust realmente trabalha com async por baixo


Aqui está a parte que costuma confundir quem vem de Python.

Em Python
Você normalmente pensa em:
corrotina
event loop
task
await

Em Rust
Por baixo, o runtime vai chamando poll() no future. O retorno pode ser:

[Link] 3/28
09/03/2026, 16:45 Python vs Rust Async

Poll::Pending → ainda não terminou

Poll::Ready(valor) → terminou e entregou o valor

O contrato oficial do trait Future é exatamente esse. [Link]

Tradução mental

Python
“Essa corrotina pausou no await .”

Rust
“Esse future foi pollado e respondeu Pending ; quando o recurso estiver pronto, o
executor tenta de novo.”

Isso é muito importante porque explica por que o async em Rust é tão eficiente: o runtime
não fica desperdiçando trabalho; ele reativa a task quando ela pode avançar. O Async
Book oficial apresenta exatamente essa visão de futures e execução dirigida por
executor/runtime. [Link].… +2

4) async não significa paralelismo


Isso vale para as duas linguagens.

Python
asyncio faz concorrência cooperativa em um event loop. Enquanto uma task está

rodando, outra task na mesma thread não roda; a troca acontece quando a task encontra
await . Python docume… +1

Rust
Também não é sinônimo de paralelismo. async quer dizer capacidade de suspender sem
bloquear a task, normalmente muito útil para rede, banco, APIs, filas, sockets, arquivos
assíncronos etc. Paralelismo real depende de múltiplas threads e do runtime/configuração.
A documentação do Async Book destaca que .await sozinho executa uma future por vez
dentro daquele fluxo, e para várias futures ao mesmo tempo você usa
composição/execução concorrente. [Link].… +1

5) Concorrência: Python gather vs Rust join!


[Link] 4/28
09/03/2026, 16:45 Python vs Rust Async

Python

import asyncio

async def a():


await [Link](1)
return 10

async def b():


await [Link](2)
return 20

async def main():


r1, r2 = await [Link](a(), b())
print(r1, r2)

Rust

async fn a() -> i32 {


tokio::time::sleep(std::time::Duration::from_secs(1)).await;
10
}

async fn b() -> i32 {


tokio::time::sleep(std::time::Duration::from_secs(2)).await;
20
}

#[tokio::main]
async fn main() {
let (r1, r2) = tokio::join!(a(), b());
println!("{r1} {r2}");
}

Correlação direta
[Link](...) lembra bastante join!

ambos esperam múltiplas operações assíncronas


a diferença é que em Rust você sente mais os tipos e o modelo de ownership

A documentação do Async Book trata explicitamente de executar múltiplas futures ao


mesmo tempo, e a std também documenta utilidades relacionadas a join para múltiplas
futures. [Link].… +1

[Link] 5/28
09/03/2026, 16:45 Python vs Rust Async

6) Esperar o primeiro que terminar: Python


wait / FIRST_COMPLETED vs Rust select!

Rust com Tokio

use tokio::sync::oneshot;

#[tokio::main]
async fn main() {
let (tx1, rx1) = oneshot::channel();
let (tx2, rx2) = oneshot::channel();

tokio::spawn(async move {
let _ = [Link]("primeiro");
});

tokio::spawn(async move {
let _ = [Link]("segundo");
});

tokio::select! {
v = rx1 => println!("rx1: {:?}", v),
v = rx2 => println!("rx2: {:?}", v),
}
}

O tokio::select! espera várias operações e segue quando uma delas fica pronta. Isso é
bem parecido, conceitualmente, com esperar o primeiro completado em asyncio .
[Link] +1

7) Spawn de tarefas: muito parecido, mas com exigências


mais fortes em Rust
Python

taskPython
= asyncio.create_task(minha_corrotina())
Executar

Rust

[Link] 6/28
09/03/2026, 16:45 Python vs Rust Async

let handle = tokio::spawn(async {


42
});
Rust

Só que em Rust aparecem exigências extras com frequência, como Send e 'static ,
dependendo de onde a task vai rodar. Isso acontece porque o runtime pode mover a task
entre threads, e Rust precisa garantir segurança de memória e de concorrência em tempo
de compilação. A documentação do Tokio mostra spawn e select! como peças centrais
do runtime assíncrono. [Link] +1

Intuição prática
Em Python você pensa:

“Criei uma task.”

Em Rust você pensa:

“Criei uma task, mas o compilador vai verificar se os dados capturados por ela podem
viver e circular de forma segura.”

Essa é uma das maiores diferenças de ergonomia entre as duas linguagens.

8) Por que existe Pin em Rust async?


Essa é a parte “estranha” para quem vem de Python.

O método poll() do trait Future recebe self: Pin<&mut Self> . A documentação


oficial de std::pin explica que Pin existe para APIs que precisam garantir que certos
valores não sejam movidos na memória depois de fixados; Future::poll é um dos
exemplos principais. [Link] +1

Tradução didática
Em Python, você não pensa nisso.

Em Rust, algumas máquinas de estado geradas por async podem depender de garantias
de posicionamento em memória para serem seguras. Então:

Python esconde esse custo conceitual


Rust expõe parte dele para preservar segurança sem GC e sem custo invisível

[Link] 7/28
09/03/2026, 16:45 Python vs Rust Async

Regra prática para iniciante


Você não precisa dominar Pin no primeiro dia para usar async em Rust.
No início, foque em:
async fn

.await

tokio::spawn

tokio::join!

tokio::select!

Depois você aprofunda Future , Poll , Pin e lifetimes assíncronos.

9) O runtime em Rust: parecido com o event loop, mas


não idêntico
Em Python, você usa [Link](...) e normalmente pensa em “o event loop vai cuidar
de tudo”. Python docume… +1

Em Rust, a linguagem te dá a sintaxe e o trait Future , mas você geralmente usa um


runtime, como Tokio, para:

agendar tasks
timers
sockets assíncronos
utilidades de coordenação

Por isso este padrão é comum:

#[tokio::main]
async fn main() {
// ...
}
Rust
Ou seja: a linguagem fornece o modelo, e o runtime fornece a infraestrutura para
executar esse modelo de forma útil em aplicações reais. O Async Book e o tutorial do
Tokio mostram exatamente essa separação entre futures e executor/runtime.
[Link].… +1

[Link] 8/28
09/03/2026, 16:45 Python vs Rust Async

10) Ownership aparece com força no async Rust


Aqui está um dos choques mais fortes para quem programa Python.

Python
Você compartilha objetos com enorme liberdade.

Rust
No async, você precisa respeitar:
ownership
borrowing
lifetimes
Send / Sync quando houver concorrência entre threads

Exemplo clássico:

let s = String::from("oi");

tokio::spawn(async move {
println!("{s}");
});
R t
O move é muito comum porque a task precisa tomar posse do que usa.

Correlação com Python


Seria como se Python obrigasse você a declarar explicitamente:

“essa task agora é dona desses dados”

Isso parece mais duro no começo, mas é justamente o que evita uma categoria enorme de
bugs de concorrência e memória.

11) Erros comuns de quem vem de Python


Erro 1: achar que async fn executa na hora
Não. Em Rust, async fn retorna um future; ele precisa ser aguardado ou executado por
um runtime. [Link] +1

Erro 2: confundir async com thread


[Link] 9/28
09/03/2026, 16:45 Python vs Rust Async

Async é ótimo para I/O concorrente. CPU pesada normalmente pede outra estratégia,
como threads dedicadas, pools ou offloading.

Erro 3: tentar usar referências emprestadas demais dentro de tasks


Em Python isso passa fácil. Em Rust o compilador barra quando a vida útil dos dados não
é segura.

Erro 4: esquecer que .await pode suspender


Toda vez que há .await , pense:

“a execução pode parar aqui e voltar depois”

Isso afeta locks, borrows e desenho da API.

12) Uma comparação direta lado a lado


Python mental model

async def f():


await algo()
Python Executar

Leitura:

“Tenho uma corrotina; quando chegar no await, o loop pode executar outra task.”

Rust mental model

async fn f() {
algo().await;
}
Rust

Leitura:

“Tenho uma função que produz um future; esse future vira uma máquina de estados;
quando chegar no .await , ele pode retornar Pending e ser retomado depois pelo
executor.”

Esse modelo de “future como máquina de estados” é a forma certa de pensar em async
Rust, alinhada ao Async Book e ao trait Future . [Link].… +2

[Link] 10/28
09/03/2026, 16:45 Python vs Rust Async

13) Exemplo mais realista: várias requisições


Python

import asyncio

async def buscar(id_):


await [Link](1)
return f"dado {id_}"

async def main():


resultados = await [Link](
buscar(1),
buscar(2),
buscar(3),
)
print(resultados)

[Link](main())

Rust

async fn buscar(id: u32) -> String {


tokio::time::sleep(std::time::Duration::from_secs(1)).await;
format!("dado {}", id)
}

#[tokio::main]
async fn main() {
let (a, b, c) = tokio::join!(
buscar(1),
buscar(2),
buscar(3),
);

println!("{:?}", vec![a, b, c]);


}

O que aprender daqui


Em Python, o foco fica no fluxo.
Em Rust, o foco fica em:
fluxo
[Link] 11/28
09/03/2026, 16:45 Python vs Rust Async

tipos
ownership
segurança de concorrência

14) Regra prática para pensar como programador Python


migrando para Rust
Use este mapa mental:

Python
“Tenho corrotinas”
“O loop agenda”
“ await cede controle”
“compartilhar objetos é fácil”

Rust
“Tenho futures”
“Um runtime/executor polla futures”
“ .await suspende a task”
“ownership e lifetimes definem o que pode viver e ser movido”
“o compilador garante segurança antes de rodar”

15) O que estudar primeiro em Rust async


A ordem mais inteligente é:

Etapa 1
Aprender a escrever e usar:

async fn
.await

Etapa 2
Aprender runtime com Tokio:

#[tokio::main]

tokio::spawn

tokio::join!

[Link] 12/28
09/03/2026, 16:45 Python vs Rust Async

tokio::select!

Etapa 3
Entender a base:
Future

Poll

Pin

Etapa 4
Dominar problemas reais:

Arc

Mutex assíncrono

canais
cancelamento
tratamento de erro

16) Resumo em uma frase


Python async te faz pensar em corrotinas e event loop.
Rust async te faz pensar em futures, máquina de estados, executor e ownership.
Python docume… +2

17) Exemplo final: a tradução mais fiel entre as linguagens


Python

import asyncio

async def trabalho(nome, atraso):


print(f"início {nome}")
await [Link](atraso)
print(f"fim {nome}")
return nome

async def main():


t1 = asyncio.create_task(trabalho("A", 2))
t2 = asyncio.create_task(trabalho("B", 1))

[Link] 13/28
09/03/2026, 16:45 Python vs Rust Async

r1 = await t1
r2 = await t2
print(r1, r2)

[Link](main())

Rust

use tokio::task::JoinHandle;
use std::time::Duration;

async fn trabalho(nome: &'static str, atraso: u64) -> &'static str {


println!("início {}", nome);
tokio::time::sleep(Duration::from_secs(atraso)).await;
println!("fim {}", nome);
nome
}

#[tokio::main]
async fn main() {
let t1: JoinHandle<&'static str> = tokio::spawn(async {
trabalho("A", 2).await
});

let t2: JoinHandle<&'static str> = tokio::spawn(async {


trabalho("B", 1).await
});

let r1 = [Link]();
let r2 = [Link]();

println!("{} {}", r1, r2);


}

O que esse exemplo ensina


asyncio.create_task() ↔ tokio::spawn(...)

await task ↔ [Link]

em Rust, o compilador participa muito mais da segurança do fluxo

Fechamento direto
Para alguém que já programa em Python, o jeito mais rápido de aprender async em Rust é
não tentar decorar teoria primeiro.

[Link] 14/28
09/03/2026, 16:45 Python vs Rust Async

Faça esta tradução mental sempre:


corrotina Python → future Rust
event loop → runtime/executor
await → ponto de suspensão

objeto compartilhado livremente → ownership/borrowing verificado pelo


compilador

Esse é o coração do assunto.

No próximo passo, eu posso te montar um guia progressivo com 5 exemplos, começando


em asyncio e reescrevendo um por um em Rust com Tokio, incluindo:
HTTP, tarefas concorrentes, canais, mutex assíncrono e tratamento de erro.

Fontes

#\[tokio::main\]

Fale agora sobre concorrência real, Threads, Paralelismo,


Channels (comunicação entre threads)

Agora eu vou conectar concorrência real em Rust com a sua base de Python, separando
bem async, threads e paralelismo, porque misturar esses três conceitos atrapalha muito
no começo.

Pensou por 12s

Perfeito. Agora entramos no ponto em que muita gente mistura tudo: async, concorrência
real, threads e paralelismo.

Vou organizar isso como um professor faria no quadro, ligando sempre com Python.

1) Primeiro: separar os conceitos corretamente


Async
async não é thread.

No ecossistema Rust com Tokio, #[tokio::main] cria e inicializa um runtime assíncrono


para executar tarefas assíncronas; o runtime contém o agendador de tasks, I/O orientada a

[Link] 15/28
09/03/2026, 16:45 Python vs Rust Async

eventos, timers etc. A própria documentação do Tokio explica que essa macro transforma
async fn main() em uma fn main() síncrona que cria o runtime e executa a função

assíncrona. [Link] +1

Concorrência
Concorrência é quando várias tarefas progridem no mesmo intervalo de tempo, mesmo
que não executem literalmente ao mesmo tempo o tempo todo.

Paralelismo
Paralelismo é quando duas ou mais coisas realmente executam ao mesmo tempo, em
mais de um núcleo/thread.

Thread
Thread é a unidade de execução do sistema operacional usada para trabalho simultâneo
real. Em Rust, a biblioteca padrão tem o módulo std::thread para isso. A documentação
da std diz explicitamente que o módulo thread contém as abstrações de threading de
Rust. [Link]

2) Comparando com Python


Python
Você já deve conhecer algo assim:
asyncio → concorrência cooperativa para I/O

threading → threads reais

multiprocessing → paralelismo real sem briga com GIL para CPU-bound

Rust
Em Rust, a divisão mental correta é:

async /Tokio → excelente para I/O concorrente


std::thread → threads reais

múltiplas threads em múltiplos núcleos → paralelismo real


channels , Mutex , Arc , atomics → comunicação e sincronização entre threads/tasks

A diferença grande é que Rust não te “esconde” segurança de concorrência. O compilador


participa do processo.

[Link] 16/28
09/03/2026, 16:45 Python vs Rust Async

3) O que #[tokio::main] faz de verdade


Como você pediu correlação com isso especificamente, vamos focar.

Quando você escreve:

#[tokio::main]
async fn main() {
// ...
}
Rust
isso não significa “agora tudo virou multithread automaticamente no sentido conceitual
que iniciantes imaginam”.

O que significa é:

1. o Tokio cria um runtime;


2. esse runtime passa a executar as suas tasks assíncronas;
3. o runtime pode ser configurado, e a macro #[tokio::main] é a forma simples de
iniciar isso. [Link] +1

A documentação do tokio::main também diz que a macro fornece configuração básica e


que, para controle maior, você usa tokio::runtime . [Link] +1

Tradução para quem vem de Python


Pense assim:
[Link](main()) em Python

#[tokio::main] async fn main() em Rust

Ambos entram em um contexto assíncrono, mas isso ainda não é a mesma coisa que criar
threads manualmente.

4) Concorrência cooperativa vs concorrência real com


threads
Async/Tokio
No async, várias tasks podem avançar de forma concorrente. Isso é ótimo para:
sockets
HTTP
[Link] 17/28
09/03/2026, 16:45 Python vs Rust Async

banco de dados
filas
timers
servidores web

Tokio descreve seu modelo como plataforma de I/O não bloqueante e orientada a
eventos, com runtime, tasks, sincronização e canais. [Link] +1

Intuição
Uma task roda até encontrar .await .
Quando ela espera algo externo, o runtime pode rodar outra task.

Isso é muito parecido com Python asyncio .

Threads reais
Quando você usa std::thread::spawn , você cria uma thread real do sistema operacional.

Exemplo:

use std::thread;

fn main() {
let handle = thread::spawn(|| {
println!("Rodando em outra thread");
});

[Link]().unwrap();
}

Aqui não é “simulação cooperativa”. É thread de verdade.

Comparação com Python


Isso é análogo a [Link](...) , só que em Rust você entra muito mais cedo em:
ownership
move

compartilhamento seguro
ausência de data race em código seguro

[Link] 18/28
09/03/2026, 16:45 Python vs Rust Async

5) Concorrência real e paralelismo: onde está a diferença


prática?
Concorrência
Você pode ter 10 tarefas competindo por progresso.

Paralelismo
Você pode ter 4 dessas tarefas rodando realmente ao mesmo tempo em 4 núcleos.

Em Rust
Se você tem várias threads, o SO pode escaloná-las em vários núcleos, dando paralelismo
real.

Em async
Você pode ter muitas tasks concorrentes, mas isso não implica automaticamente que
todas estão rodando em paralelo naquele instante.

6) Quando usar async e quando usar thread


Essa regra prática ajuda demais.

Use async quando o trabalho é I/O-bound


Exemplos:
esperar resposta HTTP
esperar query no banco
servidor TCP
WebSocket
fila de mensagens
timeout, sleep, backoff

Use threads quando o trabalho é CPU-bound ou bloqueante


Exemplos:
compressão
parsing pesado
processamento de imagem
simulação
criptografia pesada
[Link] 19/28
09/03/2026, 16:45 Python vs Rust Async

loops matemáticos pesados


biblioteca bloqueante

Tradução mental Python → Rust


asyncio → tokio
threading → std::thread

trabalho pesado que não deve travar o fluxo → thread separada ou estratégia de
offload

7) O modelo mais idiomático em Rust: message passing


Rust gosta muito de uma ideia: “não compartilhe memória se você puder trocar
mensagens”.

A documentação do livro de Rust apresenta channels exatamente como mecanismo de


message passing, e a std fornece std::sync::mpsc , onde mpsc significa multiple
producer, single consumer. [Link] +1

8) Channels entre threads


O que é um channel?
É um “cano” de comunicação:

um lado envia ( Sender )


o outro recebe ( Receiver )

A std documenta channel() como um canal assíncrono no sentido de envio não


bloqueante para o remetente com buffer “infinito” conceitual, enquanto recv() bloqueia
até receber algo ou até todos os senders serem fechados. [Link]

Exemplo simples

Rust

use std::sync::mpsc;
use std::thread;

fn main() {
let (tx, rx) = mpsc::channel();

thread::spawn(move || {
[Link] 20/28
09/03/2026, 16:45 Python vs Rust Async

let msg = String::from("olá da thread");


[Link](msg).unwrap();
});

let recebido = [Link]().unwrap();


println!("Recebido: {}", recebido);
}

O que aconteceu aqui


1. mpsc::channel() criou o canal.
2. tx é o transmissor.
3. rx é o receptor.
4. A thread filha envia a mensagem.
5. A thread principal recebe com recv() .

9) Correlação com Python


Em Python, você pode pensar em algo próximo de:

[Link]
[Link]

[Link] no mundo async

Mas em Rust o canal entra com um peso maior na arquitetura porque ele combina muito
bem com:

ownership
ausência de data race
desacoplamento entre threads

10) mpsc : múltiplos produtores, um consumidor


A std deixa isso claro: o Sender pode ser clonado, mas o Receiver é único.
[Link] +1

Exemplo

Rust

use std::sync::mpsc;
use std::thread;

[Link] 21/28
09/03/2026, 16:45 Python vs Rust Async

fn main() {
let (tx, rx) = mpsc::channel();

for i in 0..3 {
let tx_clone = [Link]();
thread::spawn(move || {
tx_clone.send(format!("mensagem da thread {}", i)).unwrap();
});
}

drop(tx);

for msg in rx {
println!("{}", msg);
}
}

ChatGPT 5.4 Thinking Memória desativada


Didática importante
O drop(tx) da thread principal é importante aqui porque, se ainda existir algum Sender
vivo, o receptor pode continuar esperando mais mensagens.

11) Canais síncronos e backpressure


Além de channel() , existe sync_channel() na std.

A documentação oficial explica que sync_channel(bound) cria um canal limitado; quando


o buffer enche, send passa a bloquear. [Link]

Exemplo

Rust

use std::sync::mpsc::sync_channel;
use std::thread;

fn main() {
let (tx, rx) = sync_channel(2);

thread::spawn(move || {
[Link](10).unwrap();
[Link](20).unwrap();
[Link](30).unwrap(); // pode bloquear até alguém consumir
});

println!("{}", [Link]().unwrap());
println!("{}", [Link]().unwrap());

[Link] 22/28
09/03/2026, 16:45 Python vs Rust Async

println!("{}", [Link]().unwrap());
}

Por que isso é útil?


Porque você controla pressão do sistema.

Em termos práticos
Se produtor está muito mais rápido que consumidor, canal ilimitado pode crescer demais.
Com buffer limitado, você cria backpressure.

12) Comunicação por mensagem vs memória


compartilhada
Existem dois estilos clássicos:

Estilo 1 — Message passing


Você usa channel .
Cada thread faz seu trabalho e envia resultados.

Estilo 2 — Shared state


Você compartilha dados com Arc<Mutex<T>> .

Rust favorece bastante o primeiro quando possível. Tokio inclusive diz que, em programas
Tokio, a forma mais comum de sincronização é message passing, com a vantagem de
evitar estado compartilhado. [Link]

13) Exemplo com memória compartilhada

Rust

use std::sync::{Arc, Mutex};


use std::thread;

fn main() {
let contador = Arc::new(Mutex::new(0));
let mut handles = vec![];

for _ in 0..10 {
let contador = Arc::clone(&contador);

[Link] 23/28
09/03/2026, 16:45 Python vs Rust Async

let handle = thread::spawn(move || {


let mut num = [Link]().unwrap();
*num += 1;
});

[Link](handle);
}

for h in handles {
[Link]().unwrap();
}

println!("Resultado: {}", *[Link]().unwrap());


}

Como pensar nisso vindo de Python


Seria como compartilhar um inteiro mutável entre threads com lock.

Mas em Rust você precisa declarar explicitamente:

Arc → posse compartilhada entre threads

Mutex → exclusão mútua

lock() → entrada na região crítica

14) Message passing vs Mutex: quando usar cada um?


Use channel quando:
quer desacoplar produtor e consumidor
quer pipeline
quer workers independentes
quer evitar estado compartilhado

Use Arc<Mutex<T>> quando:


várias threads precisam acessar o mesmo estado mutável
esse estado realmente precisa ser centralizado

Regra de ouro
Se você consegue resolver com mensagens, isso costuma simplificar o raciocínio.

15) Como isso conversa com Tokio


[Link] 24/28
09/03/2026, 16:45 Python vs Rust Async

No mundo Tokio, além de threads da std, você também tem canais assíncronos e
primitivas de sincronização próprias do runtime. A documentação de tokio::sync
destaca message passing como forma comum de sincronização em programas Tokio.
[Link]

Então há dois mundos:

Mundo sync / threads da std


std::thread

std::sync::mpsc
std::sync::Mutex

Mundo async / Tokio


tokio::spawn

tokio::sync::*

canais async
tokio::select!

Não é proibido misturar, mas precisa saber exatamente o que está fazendo.

16) Um erro muito comum de iniciante


Misturar esta ideia errada:

“Se eu usei #[tokio::main] , então tudo agora é paralelo.”

Não.

O que você ganhou foi um runtime assíncrono. Ele agenda tasks assíncronas, fornece
timers e I/O assíncrona. [Link] +1

Paralelismo real depende de execução em múltiplas threads/núcleos.

17) Outro erro comum: achar que channel é só para async


Também não.

Channels existem muito fortemente no mundo de threads da std. O módulo


std::sync::mpsc é justamente sobre isso. [Link] +1

[Link] 25/28
09/03/2026, 16:45 Python vs Rust Async

18) Fluxo mental correto para um programador Python


Aqui vai a tradução mais útil.

Em Python você costuma pensar:


“Vou usar asyncio para rede”
“Vou usar threading para rodar em paralelo”
“Vou usar queue para comunicação”

Em Rust pense assim:


“Vou usar Tokio para I/O assíncrona”
“Vou usar std::thread para threads reais”
“Vou usar mpsc ou canais async para comunicação”
“Vou usar Arc<Mutex<T>> só quando estado compartilhado for realmente necessário”

19) Exemplo completo com workers e channel


Esse exemplo já é bem prático.

Rust

use std::sync::mpsc;
use std::thread;

fn main() {
let (tx, rx) = mpsc::channel();

for i in 0..4 {
let tx = [Link]();
thread::spawn(move || {
let resultado = i * i;
[Link]((i, resultado)).unwrap();
});
}

drop(tx);

for (entrada, resultado) in rx {


println!("{}^2 = {}", entrada, resultado);
}
}

O que isso ensina


4 threads reais
[Link] 26/28
09/03/2026, 16:45 Python vs Rust Async

cada thread calcula algo


cada uma manda o resultado pelo canal
a thread principal coleta tudo

Esse padrão é excelente para:


worker pool simples
fan-out / fan-in
processamento paralelo de tarefas independentes

20) Sobre crossbeam


Embora a std ofereça std::sync::mpsc , a documentação do crossbeam::channel o
apresenta como alternativa com mais recursos e melhor desempenho. [Link]

Então, em projetos reais, muita gente usa:

std::sync::mpsc para aprender e casos simples

crossbeam::channel para cenários mais fortes

21) Resumo direto e correto


#[tokio::main]
Cria um runtime assíncrono e executa sua async fn main , não é sinônimo automático de
“threads manuais” nem de “paralelismo mágico”. [Link] +1

std::thread
É thread real do sistema operacional. [Link]

Paralelismo
Acontece quando múltiplas threads realmente executam ao mesmo tempo em múltiplos
núcleos.

std::sync::mpsc
É o canal padrão da std para message passing entre threads; mpsc significa múltiplos
produtores e um consumidor. channel() é não bloqueante no envio e sync_channel() é
limitado e pode bloquear no send . [Link] +2

[Link] 27/28
09/03/2026, 16:45 Python vs Rust Async

Padrão idiomático
Sempre que der, prefira troca de mensagens a estado compartilhado. Tokio destaca
message passing como forma comum de sincronização por evitar shared state. [Link]

22) Mapa mental final


Python
asyncio → I/O concorrente
threading → threads

queue → comunicação
multiprocessing → CPU pesado / paralelismo sem GIL

Rust
tokio → I/O concorrente async

std::thread → threads reais

mpsc / crossbeam → comunicação entre threads


Arc<Mutex<T>> → estado compartilhado quando necessário

No próximo passo, eu posso te mostrar 3 exemplos lado a lado em Python e Rust:


1. worker pool com threads,
2. pipeline com channels,
3. versão async com Tokio,

para você enxergar exatamente quando usar cada modelo.

Fontes

[Link] 28/28

Você também pode gostar