Spawning
Spawning
使你可以在后台运行新的异步任务,这可以让我们在它运行时继续执行其它代码。
假设我们有一个 Web 服务器需要在接受、处理连接时而不阻塞主线程。为了实现这点,我们可以使用 async_std::task::spawn
函数来创建并运行一个新的任务来处理这个连接。spawn
函数接收一个 feture
并返回一个 JoinHandle
,
它可用于等待任务完成后的结果。
use async_std::{task, net::TcpListener, net::TcpStream}; use futures::AsyncWriteExt; async fn process_request(stream: &mut TcpStream) -> Result<(), std::io::Error>{ stream.write_all(b"HTTP/1.1 200 OK\r\n\r\n").await?; stream.write_all(b"Hello World").await?; Ok(()) } async fn main() { let listener = TcpListener::bind("127.0.0.1:8080").await.unwrap(); loop { // Accept a new connection let (mut stream, _) = listener.accept().await.unwrap(); // Now process this request without blocking the main loop task::spawn(async move {process_request(&mut stream).await}); } }
spawn
返回实现了 Future
特征的 JoinHandle
,所以我们可以通过 .await
来获取此任务的结果。
但这将阻塞当前的任务,直至新生成的任务运行完成。如果不使用 .await
等待该任务,则程序将继续运行,
若此任务在当前函数运行结束前没有完成,则会取消此任务(即不等待结果,直接丢弃)。
#![allow(unused)] fn main() { use futures::future::join_all; async fn task_spawner(){ let tasks = vec![ task::spawn(my_task(Duration::from_secs(1))), task::spawn(my_task(Duration::from_secs(2))), task::spawn(my_task(Duration::from_secs(3))), ]; // If we do not await these tasks and the function finishes, they will be dropped join_all(tasks).await; } }
通常,我们使用 async
运行时提供的 channels
来进行主任务与派生任务的通信。