Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 如何告诉Rust让我修改隐藏在rBlock后面的共享变量?_Multithreading_Rust - Fatal编程技术网

Multithreading 如何告诉Rust让我修改隐藏在rBlock后面的共享变量?

Multithreading 如何告诉Rust让我修改隐藏在rBlock后面的共享变量?,multithreading,rust,Multithreading,Rust,Safe要求从所有参考资料中获得以下信息: 对资源的一个或多个引用(&T) 只有一个可变引用(&mut T) 我希望有一个可以由多个线程读取和一个线程写入的Vec,但一次只能有一个线程(根据语言要求) 所以我使用了rblock 我需要一个Vec。为了让它比主函数更长寿,我将它放入框中,然后在其周围插入锁,如下所示: fn main() { println!("Hello, world!"); let mut v = vec![0, 1, 2, 3, 4, 5, 6]; l

Safe要求从所有参考资料中获得以下信息:

  • 对资源的一个或多个引用(
    &T
  • 只有一个可变引用(
    &mut T
  • 我希望有一个可以由多个线程读取和一个线程写入的
    Vec
    ,但一次只能有一个线程(根据语言要求)

    所以我使用了
    rblock

    我需要一个
    Vec
    。为了让它比主函数更长寿,我将它放入框中,然后在其周围插入锁,如下所示:

    fn main() {
        println!("Hello, world!");
        let mut v = vec![0, 1, 2, 3, 4, 5, 6];
        let val = RwLock::new(Box::new(v));
        for i in 0..10 {
            thread::spawn(move || threadFunc(&val));
        }
        loop {
            let mut VecBox = (val.write().unwrap());
            let ref mut v1 = *(*VecBox);
            v1.push(1);
            //And be very busy.
            thread::sleep(Duration::from_millis(10000));
        }
    }
    fn threadFunc(val: &RwLock<Box<Vec<i8>>>) {
        loop {
            //Use Vec
            let VecBox = (val.read().unwrap());
            let ref v1 = *(*VecBox);
            println!("{}", v1.len());
            //And be very busy.
            thread::sleep(Duration::from_millis(1000));
        }
    }
    
    没有线程:

    for i in 0..10 {
        threadFunc(&val);
    }
    
    它编译。问题在于关闭。我必须“移动”它,否则Rust会抱怨它可以比
    main
    更长寿,我也不能克隆
    val
    rBlock
    没有实现
    clone()


    我该怎么办?

    注意,使用
    rBlock
    互斥锁之间没有结构上的区别;他们只是有不同的访问模式。看见
    进行相关讨论

    问题的核心是,您已经将向量的所有权(在
    rblock
    中)转移到了某个线程;因此,你的主线程不再有它了。你无法访问它,因为它不见了

    事实上,您将遇到与尝试将向量传递给每个线程相同的问题。你只有一个向量可以给出,所以只有一个线程可以得到它

    您需要线程安全共享所有权,由以下人员提供:

    使用std::sync::{Arc,RwLock};
    使用std::线程;
    使用std::time::Duration;
    fn main(){
    println!(“你好,世界!”);
    设v=vec![0,1,2,3,4,5,6];
    设val=Arc::new(RwLock::new(v));
    对于0..10中的uu{
    设v=val.clone();
    线程::生成(移动| |线程| func(v));
    }
    对于0..5中的uu{
    {
    让mut val=val.write().unwrap();
    val.push(1);
    }
    线程::睡眠(持续时间::从_毫秒(1000));
    }
    }
    fn螺纹功能(val:Arc){
    环路{
    {
    让val=val.read().unwrap();
    println!(“{}”,val.len());
    }
    线程::睡眠(持续时间::从_毫秒(100));
    }
    }
    
    其他需要注意的事项:

  • 我删除了
    main
    中的无限循环,以便代码能够真正完成
  • 我修复了所有编译器警告。如果要使用编译语言,请注意警告。
    • 不必要的括号
    • snake\u案例
      标识符。明确地不要对局部变量使用
      PascalCase
      ;这是用于类型的
      camelCase
      不用于生锈
  • 我添加了一些块,以缩短读/写锁的使用寿命。否则会有很多争用,并且子线程永远没有机会获得读锁
  • let ref v1=*(*foo)是非惯用的。首选
    让v1=&**foo
    。由于
    Deref
    ,您甚至不需要这样做

  • 请注意,使用
    RwLock
    互斥体之间没有结构上的区别;他们只是有不同的访问模式。看见
    进行相关讨论

    问题的核心是,您已经将向量的所有权(在
    rblock
    中)转移到了某个线程;因此,你的主线程不再有它了。你无法访问它,因为它不见了

    事实上,您将遇到与尝试将向量传递给每个线程相同的问题。你只有一个向量可以给出,所以只有一个线程可以得到它

    您需要线程安全共享所有权,由以下人员提供:

    使用std::sync::{Arc,RwLock};
    使用std::线程;
    使用std::time::Duration;
    fn main(){
    println!(“你好,世界!”);
    设v=vec![0,1,2,3,4,5,6];
    设val=Arc::new(RwLock::new(v));
    对于0..10中的uu{
    设v=val.clone();
    线程::生成(移动| |线程| func(v));
    }
    对于0..5中的uu{
    {
    让mut val=val.write().unwrap();
    val.push(1);
    }
    线程::睡眠(持续时间::从_毫秒(1000));
    }
    }
    fn螺纹功能(val:Arc){
    环路{
    {
    让val=val.read().unwrap();
    println!(“{}”,val.len());
    }
    线程::睡眠(持续时间::从_毫秒(100));
    }
    }
    
    其他需要注意的事项:

  • 我删除了
    main
    中的无限循环,以便代码能够真正完成
  • 我修复了所有编译器警告。如果要使用编译语言,请注意警告。
    • 不必要的括号
    • snake\u案例
      标识符。明确地不要对局部变量使用
      PascalCase
      ;这是用于类型的
      camelCase
      不用于生锈
  • 我添加了一些块,以缩短读/写锁的使用寿命。否则会有很多争用,并且子线程永远没有机会获得读锁
  • let ref v1=*(*foo)是非惯用的。首选
    让v1=&**foo
    。由于
    Deref
    ,您甚至不需要这样做

  • 谢谢,不过
    drop()
    变量不是比破解作用域更惯用吗?@CharlesShiller。因此,不,块是最常用的。@E_net4在这种情况下,
    drop
    应该可以工作,因为锁看起来不像是可变的借用。我不知道其中一个比另一个更地道
    drop(vec)
    对我来说只是有些奇怪。另外,可能是我身上的C,但是
    &**foo
    *foo
    不同吗?@Charleshiller请查看详细信息。TL;DR,Rust具有
    Deref
    的特性,这意味着
    &*
    并不总是不可操作的。谢谢,尽管它不是更习惯于
    use std::sync::{Arc, RwLock};
    use std::thread;
    use std::time::Duration;
    
    fn main() {
        println!("Hello, world!");
        let v = vec![0, 1, 2, 3, 4, 5, 6];
        let val = Arc::new(RwLock::new(v));
    
        for _ in 0..10 {
            let v = val.clone();
            thread::spawn(move || thread_func(v));
        }
    
        for _ in 0..5 {
            {
                let mut val = val.write().unwrap();
                val.push(1);
            }
            thread::sleep(Duration::from_millis(1000));
        }
    }
    
    fn thread_func(val: Arc<RwLock<Vec<i8>>>) {
        loop {
            {
                let val = val.read().unwrap();
                println!("{}", val.len());
            }
            thread::sleep(Duration::from_millis(100));
        }
    }