Task
Rust یک task system دارد که نوعی thread سبک وزن است.
یک task یک future در سطح بالا دارد که اجراکننده (executor) برای ادامه کار آن را poll میکند. آن future ممکن است یک یا چند future تودرتو داشته باشد که متد poll
آن را poll
میکند، که به طور ناپایداری با یک stack فراخوانی شده مطابقت دارد. همزمانی در یک task با poll از چندین child future، مانند رقابت یک تایمر و یک عملیات I/O امکانپذیر است.
use tokio::io::{self, AsyncReadExt, AsyncWriteExt}; use tokio::net::TcpListener; #[tokio::main] async fn main() -> io::Result<()> { let listener = TcpListener::bind("127.0.0.1:0").await?; println!("listening on port {}", listener.local_addr()?.port()); loop { let (mut socket, addr) = listener.accept().await?; println!("connection from {addr:?}"); tokio::spawn(async move { socket.write_all(b"Who are you?\n").await.expect("socket error"); let mut buf = vec![0; 1024]; let name_size = socket.read(&mut buf).await.expect("socket error"); let name = std::str::from_utf8(&buf[..name_size]).unwrap().trim(); let reply = format!("از تماس تلفنی متشکریم، {name}!\n"); socket.write_all(reply.as_bytes()).await.expect("socket error"); }); } }
این مثال را در src/main.rs
آماده شده خود کپی کنید و آن را از آنجا اجرا کنید.
سعی کنید با یک ابزار اتصال TCP مانند nc یا telnet به آن متصل شوید.
-
Ask students to visualize what the state of the example server would be with a few connected clients. What tasks exist? What are their Futures?
-
This is the first time we've seen an
async
block. This is similar to a closure, but does not take any arguments. Its return value is a Future, similar to anasync fn
. -
بلوک async را به یک تابع تغییر دهید و مدیریت خطا را با استفاده از
?
بهبود بخشید.