tokio mpsc channel

预期行为是:
要求用户随机输入(q退出)
将相同的输入打印到标准输出

将std::io::stdin()替换为tokio::io::stdin()还需要将标准库BufReader替换为tokio的实现,该实现封装了R: AsyncRead而不是R: Read。

为了防止输入任务和输出任务之间的交叉写入,可以使用一个响应器通道,在输出已打印时向输入任务发送信号。

use std::error::Error;
use tokio::io::{AsyncBufReadExt, AsyncWriteExt};
use tokio::sync::{mpsc, oneshot};

#[derive(Debug)]
struct Message {
    done_tx: oneshot::Sender<()>,
    message: String,
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    let (tx, mut rx) = mpsc::unbounded_channel::<Message>();

    let printer = tokio::spawn(async move {
        while let Some(Message {
            message: m,
            done_tx,
        }) = rx.recv().await
        {
            if m.trim() == "q".to_string() {
                break;
            }
            println!("Received: {}", m.trim());
            done_tx.send(()).unwrap();
        }
        println!("Printer exited");
    });

    let input_message = tokio::spawn(async move {
        let stdin = tokio::io::stdin();
        let mut stdout = tokio::io::stdout();
        let mut bufr = tokio::io::BufReader::new(stdin);
        let mut buf = String::new();
        loop {
            // Let the printer thread print the string before asking the user's input.
            stdout.write(b"Enter input: ").await.unwrap();
            stdout.flush().await.unwrap();
            bufr.read_line(&mut buf).await.unwrap();

            let end = buf.trim() == "q";
            let (done_tx, done) = oneshot::channel();
            let message = Message {
                message: buf,
                done_tx,
            };
            tx.send(message).unwrap();
            if end {
                break;
            }
            done.await.unwrap();

            buf = String::new();
        }
        println!("InputMessage exited");
    });

    tokio::join!(input_message, printer);
    Ok(())
}

Enter input: 1
Received: 1
Enter input: 2
Received: 2
Enter input: 3
Received: 3
Enter input: q
InputMessage exited
Printer exited

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值