rust - 你如何将 Vec 的切片发送到 Rust 中的任务?

标签 rust

所以,这是行不通的:

use std::comm;

#[deriving(Show)]
struct St { v: u8 }

fn main() {

  let mut foo:Vec<St> = Vec::new();
  for i in range(0u8, 10) {
    foo.push(St { v: i });
  }

  {
      let mut foo_slice = foo.as_mut_slice();
      let (f1, f2) = foo_slice.split_at_mut(5);

      let (sl, rx):(Sender<Option<&mut [St]>>, Receiver<Option<&mut [St]>>) = comm::channel();
      let (sx, rl):(Sender<bool>, Receiver<bool>) = comm::channel();

      spawn(proc() {
        loop {
          let v = rx.recv();
          match v {
            Some(v) => {
                v[0].v = 100u8;
                sx.send(true);
            },
            None => {
                sx.send(false);
                break;
            }
          }
        }
      });

      sl.send(Some(f1));
      sl.send(Some(f2));
      sl.send(None);

      println!("{}", rl.recv());
      println!("{}", rl.recv());
      println!("{}", rl.recv());
  }

  println!("{}", foo);
}

...因为:

sl.send(Some(f1));
sl.send(Some(f2));
sl.send(None);

推断变量 f1 和 f2 必须是 'static,因为任务可能比它运行的函数长寿。这反过来意味着 foo 必须是 'static,而不是 'a,这是 main( ).

因此有点奇怪的错误:

<anon>:14:27: 14:30 error: `foo` does not live long enough
<anon>:14       let mut foo_slice = foo.as_mut_slice();
                                    ^~~
note: reference must be valid for the static lifetime...
<anon>:6:11: 46:2 note: ...but borrowed value is only valid for the block at 6:10
<anon>:6 fn main() {
<anon>:7  
<anon>:8   let mut foo:Vec<St> = Vec::new();
<anon>:9   for i in range(0u8, 10) {
<anon>:10     foo.push(St { v: i });
<anon>:11   }

因此,为了解决这个问题,我认为使用 Box > 可能是解决方案,但即便如此,创建的切片也将具有本地生命周期。

我可以使用不安全的代码来改变生命周期(这确实有效),但是有没有办法安全地做同样的事情?

围栏:http://is.gd/WQBdSB

最佳答案

Rust 阻止您在多个任务中对同一值进行可变访问,因为这会导致数据竞争。具体来说,任务不能借用指针(包括切片)指向另一个任务拥有的值。

要允许多个任务访问同一个对象,你应该使用 Arc<T> .要提供对对象的可变访问,请放置 RefCell<T> 在那Arc : Arc<RefCell<T>> .至于那个T ,你不能使用切片类型,正如我刚才解释的那样。我建议你创建 2 个不同的 Arc<RefCell<Vec<St>>>对象,发送一个 Arc<RefCell<Vec<St>>> 的克隆在 channel 上加入 Vec s 当任务完成它们的工作时。

一般来说,在做并行算法时,你应该避免改变共享状态。这会导致性能不佳,因为系统需要跨内核使内存缓存失效。如果可能,考虑让任务分配并保留其结果直到完成,然后通过 channel 发送完整的结果,而不仅仅是 bool。 .

编辑

我们可以根据所有权重新制定您的初始计划,以了解其不合理的原因。调用 main 的堆栈帧拥有foo , Vec . foo_slice , f1f2借那个Vec .你产生了一个任务。 该任务可能比 main 的调用框架还长,甚至比产生它的任务还长。因此,发送对受限于堆栈帧的值的引用是非法的。这就是为什么借用指针的原因,&'static T 除外。 , 不满足 Send .

装箱Vec什么都没有改变,因为栈帧仍然拥有 Box , 因此从该函数返回时将丢弃该框及其内容。

编译器无法验证任务不会比您向任务发送引用的值的所有者存在时间更长。如果您确定任务将在您提供的引用失效之前终止,您可以使用 transmute 欺骗一生,但这是不安全的。

关于rust - 你如何将 Vec 的切片发送到 Rust 中的任务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26477757/

相关文章:

rust - 不能对返回 Result<(), error> 的函数使用 `?` 运算符

rust - 如何检查我的内存分配是否正确?

rust - 如何使用跟踪订阅者设置自定义时间戳格式?

rust - 如何创建具有计时时区的通用 Rust 结构?

rust - 如何从 Rocket 端点返回状态值?

rust - 如何访问存储在 Vec 中的选项类型?

rust - 如何迭代一片映射切片?

rust - 如何在 Rust 中使用按位运算检查文件是否可执行?

sorting - 如何对 `NaN` 进行排序,使其大于任何其他数字,并等于任何其他 `NaN` ?

rust - 理解 Rust 中所有权的设计决策