问题描述
我不确定在以下情况下使用standard library's channel implementation会发生什么情况。
案例1
let (tx,rx) = std::sync::mpsc::unbounded_channel();
// some code where multiple producers are sending data through tx
tokio::spawn(async move {
while let Some(message) = rx.recv().await {
//do something with message
}
})
案例2
let (tx,rx) = std::sync::mpsc::unbounded_channel();
// some code where multiple producers are sending data through tx
tokio::spawn(async move {
while let Some(message) = rx.try_recv().await {
//do something with message }
}
})
在两种情况下,当信道为空并且接收方正在等待某些消息时,由于run_queue
被阻止,情况1的Tokio任务会停留在recv()
中吗?
另一方面,由于try_recv()
没有阻塞,Tokio任务是否会离开运行队列,以便线程在没有消息可读取时可以执行其他任务?
解决方法
深入研究源代码后,我的结论是,当Tokio通道等待消息时,它们会从运行队列中移出。使用Tokio时,在接收方上调用recv()
永远不会是阻塞代码。
我还怀疑futures::stream::stream::poll_next()
是否会被阻止,但是与Tokio频道一样,当某些值可用时,它们会被唤醒。