gpt4 book ai didi

rust - 我可以通过在两个异步接收器上调用 select 来错过一个值吗?

转载 作者:行者123 更新时间:2023-12-03 11:25:04 25 4
gpt4 key购买 nike

是否有可能,如果一个任务发送到 a另一个(同时)发送到 b ,那 tokio::select!ab通过取消剩余的 future 来降低值(value)之一?还是保证在下一次循环迭代时收到?

use tokio::sync::mpsc::Receiver;

async fn foo(mut a: Receiver<()>, mut b: Receiver<()>) {
loop {
tokio::select!{
_ = a.recv() => {
println!("A!");
}
_ = b.recv() => {
println!("B!");
}
}
}
}
我想不通 async 背后真正发生的事情魔法在这种情况下。

最佳答案

它似乎没有在任何地方的文档中得到保证,但由于基于 rust 轮询架构的工作方式,它可能适用于直接从 channel 读取。选择相当于以随机顺序轮询每个 future ,直到其中一个准备好,或者如果没有准备好,则等待直到唤醒唤醒器,然后重复该过程。只有在成功轮询返回时才会从 channel 中删除消息。成功的轮询会停止选择,因此不会触及其余 channel 。因此,它们将在下一次循环发生时被轮询,然后返回消息。
然而,这是一种危险的方法,因为如果接收器被替换为返回一个比直接读取更复杂的 future 的东西,它可能会在读取后挂起,那么在发生这种情况时你可能会丢失消息。因此,它可能应该被视为不起作用。一种更安全的方法是将 future 存储在可变变量中,并在它们触发时更新:

use tokio::sync::mpsc::Receiver;

async fn foo(mut a: Receiver<()>, mut b: Receiver<()>) {
let mut a_fut = a.recv();
let mut b_fut = b.recv();
loop {
tokio::select!{
_ = a_fut => {
println!("A!");
a_fut = a.recv();
}
_ = b_fut => {
println!("B!");
b_fut = b.recv();
}
}
}
}

关于rust - 我可以通过在两个异步接收器上调用 select 来错过一个值吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63960185/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com