【问题标题】:Using send() (mpsc::Sender) inside a loop在循环中使用 send() (mpsc::Sender)
【发布时间】:2021-12-04 16:29:12
【问题描述】:

我是 Rust 的新手,如果这个问题看起来不合适或很愚蠢,很抱歉。

我正在尝试从 TCP 流 stream 读取数据并使用 let (sender_buff, receiver_buff) = ::std::sync::mpsc::channel(); 将其发送到另一个线程。

这是我的代码:

const FRAME_SIZE:usize = 256;
let mut raw_bytes = [0 as u8; FRAME_SIZE];

let mut time_out = false;
while !time_out {
    if stream.read_exact(&mut raw_bytes).is_ok() {
        // send in the channel
        sender_buff.send(&mut raw_bytes).ok();
    } 

但是它没有编译:

error[E0499]: cannot borrow `raw_bytes` as mutable more than once at a time

我不知道如何解决这个问题,有什么想法吗? 谢谢。

【问题讨论】:

  • 您可能想要克隆您发送到频道的帧。否则(如果是 C),您将发送缓冲区,并在下一次迭代中立即开始覆盖缓冲区,因此接收线程可以接收任何内容。 (因为它是生锈的,它告诉你你做错了什么)
  • 为每个新帧分配一个新缓冲区也应该有效。

标签: rust tcp channel


【解决方案1】:

您要做的是向缓冲区发送&mut 引用,这不是一个好主意。

为了争论,想象一下 rust 允许你这样做:

  1. 该缓冲区是堆栈分配的,因此一旦您退出该函数,接收器将有一个指向未初始化内存的指针,即 UB
  2. 该函数可能会在接收器仍在读取该缓冲区时覆盖该缓冲区 - 这也会导致您的应用程序中难以检测到错误。

相反,rust 可以保护您免受这两种错误情况的影响。

您需要做的是使用堆分配的缓冲区 (Vec<T>) 并发送缓冲区本身而不是引用。这样可以保护您免受 (1) 的影响。由于移动语义,这将迫使您在每次迭代中创建一个新缓冲区,这将保护您免受 (2)

【讨论】:

    猜你喜欢
    • 2021-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-14
    • 2014-11-15
    相关资源
    最近更新 更多