Tworzenie aplikacji asynchronicznych za pomocą Tokio
Nauczą się Państwo używać runtime’u Tokio do wydajnego wykonywania zadań asynchronicznych oraz obsługi operacji wejścia-wyjścia i innych operacji współbieżnych.
Tworzenie aplikacji asynchronicznych za pomocą Tokio to bezpłatna lekcja Learn Rust Coding na CoddyKit. To lekcja 2 z 3. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Learn Rust Coding, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Learn Rust Coding zawiera 3 lekcji w sumie.
Poznajemy środowisko uruchomieniowe Tokio
Witamy ponownie! W poprzedniej lekcji poznali Państwo elementy async i await. Ale jak właściwie uruchamiana jest funkcja async?
Właśnie tutaj przydaje się asynchroniczne środowisko uruchomieniowe, takie jak Tokio. Tokio to zaawansowana biblioteka udostępniająca środowisko wykonywania asynchronicznego kodu Rust.
- Planuje i wykonuje obiekty typu
Future. - Obsługuje nieblokujące operacje wejścia-wyjścia.
- Efektywnie zarządza współbieżnymi zadaniami.
Uruchamianie kodu asynchronicznego
Aby rozpocząć pracę z Tokio, zwykle używa się makra atrybutu #[tokio::main]. To makro przekształca funkcję async fn main() w standardową funkcję fn main(), która inicjalizuje środowisko uruchomieniowe Tokio i wykonuje kod asynchroniczny.
Można traktować je jako punkt wejścia aplikacji asynchronicznej.
use tokio;
#[tokio::main]
async fn main() {
println!("Hello from Tokio!");
}Tworzenie nowych zadań asynchronicznych
Jedną z podstawowych funkcji Tokio jest możliwość równoczesnego wykonywania wielu operacji asynchronicznych. Można to osiągnąć za pomocą tokio::spawn.
tokio::spawn przyjmuje obiekt typu Future i planuje jego wykonanie w środowisku uruchomieniowym Tokio. Dzięki temu główne zadanie może dalej działać, podczas gdy utworzone zadanie wykonuje się w tle.
- Nie blokuje wykonywania.
- Zwraca obiekt
JoinHandle, którego można użyć do oczekiwania na zakończenie zadania. - Zadania działają niezależnie.
<code>tokio::spawn</code> w praktyce
Zobaczmy, jak tokio::spawn pozwala wykonywać kod współbieżnie. Proszę zauważyć, że pojawiają się oba komunikaty, ale komunikat „done” może zostać wyświetlony przed komunikatem „task complete” z powodu uśpienia.
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.");
}Oczekiwanie na wiele zadań
Gdy mają Państwo wiele zadań, często trzeba zaczekać na zakończenie wszystkich z nich. Tokio udostępnia do tego celu makro tokio::join!.
tokio::join! pozwala współbieżnie oczekiwać na wiele obiektów typu Future i połączyć ich wyniki. Działa podobnie do oczekiwania za pomocą `await` na wielu obiektach `JoinHandle`, ale często jest bardziej zwięzłe w przypadku stałego zestawu obiektów typu Future.
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);
}Asynchroniczne operacje na plikach za pomocą Tokio
Tradycyjne operacje na plikach mogą blokować wątek, co jest niekorzystne w aplikacjach asynchronicznych. Moduł tokio::fs biblioteki Tokio udostępnia asynchroniczne wersje operacji na systemie plików.
Dzięki temu aplikacja pozostaje responsywna nawet podczas odczytywania dużych plików lub wykonywania wielu operacji na plikach, ponieważ operacje wejścia-wyjścia są obsługiwane w sposób nieblokujący.
tokio::fs::read_to_stringtokio::fs::writetokio::fs::Filezapewniający większą kontrolę
Asynchroniczne odczytywanie pliku
Oto sposób asynchronicznego odczytywania pliku za pomocą tokio::fs::read_to_string. Aby ten kod zadziałał, należy upewnić się, że w tym samym katalogu co projekt Rust znajduje się plik o nazwie hello.txt (na przykład w src/ lub w katalogu głównym projektu) zawierający dowolną treść.
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),
}
}Asynchroniczne operacje sieciowe
Tokio pokazuje pełnię swoich możliwości w programowaniu sieciowym. Jego moduł tokio::net oferuje nieblokujące mechanizmy komunikacji TCP i UDP.
Ma to kluczowe znaczenie podczas tworzenia wydajnych serwerów lub klientów, które mogą jednocześnie obsługiwać wiele połączeń bez tworzenia osobnego wątku dla każdego z nich.
tokio::net::TcpListenerdla serwerów.tokio::net::TcpStreamdla połączeń klienckich.
Podstawowa struktura asynchronicznego serwera TCP
Choć pełny serwer jest złożony, ten fragment pokazuje główną pętlę asynchronicznego serwera TCP korzystającego z Tokio. Nasłuchuje on przychodzących połączeń i wyświetla komunikat dla każdego z nich. Proszę uruchomić ten kod, a następnie otworzyć w przeglądarce adres http://127.0.0.1:8080, aby zobaczyć połączenia.
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) { /* ... */ } // PlaceholderWyzwanie: zadania Tokio
Proszę przeanalizować poniższy kod Rust korzystający z Tokio. Jaki będzie *pierwszy* komunikat wyświetlony w konsoli po uruchomieniu programu?
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.");
}Podsumowanie: tworzenie aplikacji za pomocą Tokio
Wykonali Państwo ważny krok w kierunku tworzenia aplikacji asynchronicznych w Rust i Tokio!
- Tokio pełni funkcję środowiska uruchomieniowego async, wykonującego kod
async. #[tokio::main]jest asynchronicznym punktem wejścia programu.tokio::spawnpozwala równocześnie uruchamiać wiele zadań.tokio::join!pomaga oczekiwać na wiele obiektów typu Future.- Tokio zapewnia nieblokujące operacje wejścia-wyjścia dla plików (
tokio::fs) i sieci (tokio::net).
Te narzędzia są podstawą tworzenia wysoce współbieżnych i responsywnych aplikacji w Rust. Proszę dalej ćwiczyć!
Ucz się Rust dzięki korepetycjom AI — za darmo
Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.
- Kursy
- 39
- Lekcje
- 144
Często zadawane pytania
Czy lekcja „Tworzenie aplikacji asynchronicznych za pomocą Tokio” jest bezpłatna?
Tak — pełny tekst „Tworzenie aplikacji asynchronicznych za pomocą Tokio” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Learn Rust Coding, przejdź na CoddyKit PRO. Kurs Learn Rust Coding zawiera 3 lekcji w sumie.
Co nauczysz się w „Tworzenie aplikacji asynchronicznych za pomocą Tokio”?
Nauczą się Państwo używać runtime’u Tokio do wydajnego wykonywania zadań asynchronicznych oraz obsługi operacji wejścia-wyjścia i innych operacji współbieżnych. Ćwiczysz Learn Rust Coding z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Learn Rust Coding?
Nie wymagamy żadnego doświadczenia. Learn Rust Coding w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 3.
Ile czasu zajmuje lekcja „Tworzenie aplikacji asynchronicznych za pomocą Tokio”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Learn Rust Coding?
Tak. Każda lekcja Learn Rust Coding zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Wprowadzenie do Async/Await
- Tworzenie aplikacji asynchronicznych za pomocą Tokio
- Praca z futures i zadaniami