在用Tokio做一些测试时,我注意到,当使用tokio::io::split将写入器和读取器发送到不同的任务时,读取器部分从不等待写入器关闭,也不会等待写入部分在另一个任务中完成时进行任何写入. 我试着在文件上找到,但没有什么可以解释这一点的原因. 我是不是错过了什么?

这是一个重现它的最小代码.

use std::io::Cursor;

use tokio::io::{self, AsyncReadExt, AsyncWriteExt};
use tokio::spawn;

#[tokio::main]
async fn main() {
    let a = Cursor::new(vec![]);
    let (mut read, mut write) = io::split(a);

    spawn(async move {
        for i in 0..10 {
            write.write_all(&[i]).await.unwrap();
        }
    });

    let mut output = vec![];

    let written = read.read_buf(&mut output).await.unwrap();
    assert_eq!(written, 10);
}

它可以从here开始执行.

操场上的输出如下:

Execution
Format
Share
Close
Standard Error
   Compiling playground v0.0.1 (/playground)
    Finished dev [unoptimized + debuginfo] target(s) in 1.60s
     Running `target/debug/playground`
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `0`,
 right: `10`', src/main.rs:20:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Standard Output

它只返回0而不是10. 我认为这是因为Cursor<Vec<_>>的唤醒程序总是处于准备状态是有意义的,因为没有执行IO(假设),除非您正在将数据从其他地方通过管道传输到游标中. 我也try 了yield_nowsleep,但它从未得到任何写入的数据. 我还确保写入器被移动,以便它可以在丢弃时刷新和剩余数据,并关闭它可能拥有的任何句柄.

在正常的游标中,我必须将其定位到位置0,但是,这不会违背拆分的目的吗?

推荐答案

这并不是真正的预期用例.Tokio的io::split主要是为了方便具有完全独立的读写流的网络流(TCP、Unix套接字等).它不适用于读写流不独立的文件和Cursor之类的对象.

您在Cursor中观察到的问题是,它只有一个读取和写入的"位置".对于每次读取,您could寻求为零,但是由于查找步骤与读取步骤不同,写入可能在中间发生,并导致您未命中和/或错误解释数据.

如果你想在线程之间共享数据,为什么不是一个简单的channelduplex流呢?

Rust相关问答推荐

使用Rust s serde_json对混合数据类型进行优化'

Rust中的相互递归特性与默认实现

在没有引用计数或互斥锁的情况下,可以从Rust回调函数内的封闭作用域访问变量吗?

为什么`Vec i64`的和不知道是`Option i64`?

如何格式化传入Rust中mysql crate的Pool::new的字符串

integer cast as pointer是什么意思

无法从流中读取Redis请求

创建Rust中元对象协议的动态对象 Select /重新分配机制

如何在Rust中缩短数组

减少指示ProgressBar在Rust中的开销

为什么我可以使用 &mut (**ref) 创建两个实时 &mut 到同一个变量?

为什么我的trait 对象类型不匹配?

实现AsyncWrite到hyper Sender时发生生命周期错误

如何在 Emacs Elisp 中获得类似格式化的 LSP?

无法理解 Rust 对临时值的不可变和可变引用是如何被删除的

为什么在 rust 中删除 vec 之前应该删除元素

Rust,使用枚举从 HashMap 获取值

如何在 C++ 和 Rust 之间共享 pthread 同步原语?

为什么 match 语句对引用类型比函数参数更挑剔?

如何阅读 HttpRequest 主体