当您调用标准库的通道recv或try_recv方法时,在Tokio的run_queue中会发生什么?

问题描述

我不确定在以下情况下使用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频道一样,当某些值可用时,它们会被唤醒。