Creare applicazioni asincrone con Tokio
Utilizzi il runtime Tokio per eseguire in modo efficiente attività asincrone e gestire l’I/O e altre operazioni concorrenti.
Creare applicazioni asincrone con Tokio è una lezione Learn Rust Coding gratuita su CoddyKit. Questa è la lezione 2 di 3. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Learn Rust Coding, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Learn Rust Coding include 3 lezioni in totale.
Presentazione del runtime Tokio
Ben tornato! Nella lezione precedente ha imparato a conoscere async e await. Ma come viene eseguita effettivamente una funzione async?
È qui che entra in gioco un runtime asincrono come Tokio. Tokio è una potente libreria che fornisce l'ambiente di esecuzione per il codice asincrono Rust.
- Pianifica ed esegue i
Future. - Gestisce le operazioni di I/O non bloccanti.
- Gestisce in modo efficiente le attività concorrenti.
Esecuzione del codice asincrono
Per iniziare a usare Tokio, in genere si utilizza la macro attributo #[tokio::main]. Questa macro trasforma la funzione async fn main() in una normale fn main() che inizializza il runtime Tokio ed esegue il codice asincrono.
La si può considerare il punto di ingresso dell'applicazione asincrona.
use tokio;
#[tokio::main]
async fn main() {
println!("Hello from Tokio!");
}Creazione di nuove attività asincrone
Una delle funzionalità fondamentali di Tokio è la possibilità di eseguire più operazioni asincrone contemporaneamente. È possibile farlo usando tokio::spawn.
tokio::spawn riceve un Future e ne pianifica l'esecuzione sul runtime di Tokio. In questo modo l'attività principale può continuare a essere eseguita mentre l'attività avviata viene eseguita in background.
- Non è bloccante.
- Restituisce un
JoinHandleper attenderne il completamento. - Le attività vengono eseguite in modo indipendente.
<code>tokio::spawn</code> in azione
Vediamo come tokio::spawn consenta di eseguire il codice contemporaneamente. Notate che vengono visualizzati entrambi i messaggi, ma il messaggio "done" potrebbe essere stampato prima di "task complete" a causa dell'attesa.
use tokio::time::{sleep, Duration};
#[tokio::main]
async fn main() {
// Spawn a new task
let handle = tokio::spawn(async {
sleep(Duration::from_secs(1)).await;
println!("Async task complete!");
});
println!("Main task continuing...");
// Wait for the spawned task to finish
handle.await.unwrap();
println!("All tasks done.");
}Attendere più attività
Quando avete più attività, spesso dovete attendere che siano completate tutte. Tokio mette a disposizione la macro tokio::join! proprio per questo scopo.
tokio::join! consente di attendere contemporaneamente più future e di combinarne i risultati. È simile ad attendere più JoinHandle con `await`, ma spesso è più concisa quando l'insieme di future è fisso.
use tokio::time::{sleep, Duration};
#[tokio::main]
async fn main() {
let task1 = async {
sleep(Duration::from_secs(1)).await;
println!("Task 1 finished");
1
};
let task2 = async {
sleep(Duration::from_millis(500)).await;
println!("Task 2 finished");
2
};
let (result1, result2) = tokio::join!(task1, task2);
println!("Results: {}, {}", result1, result2);
}I/O asincrono sui file con Tokio
Le operazioni tradizionali sui file possono bloccare il thread, il che è un problema per le applicazioni asincrone. Il modulo tokio::fs di Tokio fornisce versioni asincrone delle operazioni sul file system.
In questo modo l'applicazione rimane reattiva anche durante la lettura di file di grandi dimensioni o l'esecuzione di molte operazioni sui file, perché l'I/O viene gestito in modo non bloccante.
tokio::fs::read_to_stringtokio::fs::writetokio::fs::Fileper un controllo maggiore
Leggere un file in modo asincrono
Ecco come leggere un file in modo asincrono usando tokio::fs::read_to_string. Per eseguire questo codice, assicuratevi di avere un file denominato hello.txt nella stessa directory del progetto Rust, ad esempio all'interno di src/ o nella directory radice del progetto, con del contenuto.
use tokio::fs;
#[tokio::main]
async fn main() {
let path = "hello.txt";
// Create a dummy file for the example if it doesn't exist
// In a real app, you'd handle file creation/existence more robustly
if let Err(_) = fs::metadata(path).await {
fs::write(path, "Hello, Tokio file!").await.unwrap();
}
match fs::read_to_string(path).await {
Ok(content) => println!("File content: '{}'", content),
Err(e) => eprintln!("Error reading file: {}", e),
}
}Operazioni di rete asincrone
Tokio dà il meglio di sé nella programmazione di rete. Il suo modulo tokio::net offre primitive non bloccanti per la comunicazione TCP e UDP.
Questo è fondamentale per creare server o client ad alte prestazioni in grado di gestire molte connessioni contemporaneamente senza un thread separato per ciascuna di esse.
tokio::net::TcpListenerper i server.tokio::net::TcpStreamper le connessioni dei client.
Struttura di base di un server TCP asincrono
Sebbene un server completo sia complesso, questo frammento mostra il ciclo principale di un server TCP asincrono che usa Tokio. Il server resta in ascolto delle connessioni in arrivo e stampa un messaggio per ciascuna di esse. Provate a eseguire il codice, quindi aprite il browser all'indirizzo http://127.0.0.1:8080 per visualizzare le connessioni.
use tokio::net::TcpListener;
#[tokio::main]
async fn main() {
let listener = TcpListener::bind("127.0.0.1:8080").await.unwrap();
println!("Listening on: {}", listener.local_addr().unwrap());
loop {
let (socket, addr) = listener.accept().await.unwrap();
println!("Accepted connection from: {}", addr);
// In a real server, you'd spawn a task to handle the socket
// tokio::spawn(async move { handle_connection(socket).await; });
}
}
// fn handle_connection(socket: TcpStream) { /* ... */ } // PlaceholderSfida sulle attività di Tokio
Considerate il seguente codice Rust che usa Tokio. Quale sarà il *primo* messaggio stampato nella console quando il programma verrà eseguito?
use tokio::time::{sleep, Duration};
#[tokio::main]
async fn main() {
tokio::spawn(async {
sleep(Duration::from_millis(200)).await;
println!("Task 1: Done");
});
tokio::spawn(async {
sleep(Duration::from_millis(100)).await;
println!("Task 2: Done");
});
println!("Main: Starting tasks...");
sleep(Duration::from_millis(300)).await;
println!("Main: Finishing.");
}Riepilogo: creare applicazioni con Tokio
Avete compiuto un passo importante nella creazione di applicazioni asincrone con Rust e Tokio!
- Tokio funge da runtime asincrono ed esegue il codice
async. #[tokio::main]è il punto di ingresso asincrono del programma.tokio::spawnconsente di eseguire più attività contemporaneamente.tokio::join!aiuta ad attendere più future.- Tokio fornisce I/O non bloccante per file (
tokio::fs) e reti (tokio::net).
Questi strumenti sono fondamentali per creare applicazioni Rust altamente concorrenti e reattive. Continuate a esercitarvi!
Domande Frequenti
La lezione «Creare applicazioni asincrone con Tokio» è gratuita?
Sì — il testo completo di «Creare applicazioni asincrone con Tokio» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Learn Rust Coding, passa a CoddyKit PRO. Il corso Learn Rust Coding include 3 lezioni in totale.
Cosa imparerò in «Creare applicazioni asincrone con Tokio»?
Utilizzi il runtime Tokio per eseguire in modo efficiente attività asincrone e gestire l’I/O e altre operazioni concorrenti. Eserciti Learn Rust Coding con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Learn Rust Coding?
Non è richiesta alcuna esperienza precedente. Learn Rust Coding su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 3.
Quanto tempo richiede la lezione «Creare applicazioni asincrone con Tokio»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Learn Rust Coding?
Sì. Ogni lezione Learn Rust Coding include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Introduzione ad Async/Await
- Creare applicazioni asincrone con Tokio
- Lavorare con Future e task