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");
        });
    }
}
This slide should take about 6 minutes.

این مثال را در 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 an async fn.

  • بلوک async را به یک تابع تغییر دهید و مدیریت خطا را با استفاده از ? بهبود بخشید.