当我跑步时
use tokio::sync::mpsc;
#[tokio::main(flavor = "multi_thread", worker_threads = 1)]
async fn main() {
let (tx, mut rx) = mpsc::channel(1);
tokio::spawn(async move {
while let Some(i) = rx.recv().await {
println!("got = {}", i);
}
});
for i in 0..5 {
// busy calculation
std::thread::sleep(std::time::Duration::from_millis(10));
match tx.try_send(i) {
Ok(_) => {
println!("sent = {}", i);
},
Err(err) => {
println!("{}", err);
}
};
};
}
我得到了
sent = 0
got = 0
sent = 1
got = 1
sent = 2
got = 2
sent = 3
got = 3
sent = 4
据我了解,唯一的工作者正在处理 for 循环,因为它从不产生结果。唯一的工作者应该没有机会处理接收。因此,通道在第一次发送后应该是满的。结果我错了。我遗漏了什么?
函数中的代码
#[tokio::main]
实际上并不在工作线程上运行。因此,生成的任务被发送到唯一的工作线程,而循环则for
在程序的主线程上执行。在底层,
tokio::main
将函数体提升为一个async
块,构建一个运行时,然后将生成的异步块的未来传递给Runtime::block_on
。根据此方法的文档:您可以通过两种方式实现您的期望。
第一种方法是将函数主体提升
main
到新任务中:第二种是使用“当前线程”运行时,而不是多线程运行时。这将在主线程上运行所有任务。
这两者都会显示“已发送 = 0”,然后
try_send
会因“无可用容量”而失败。