首页 > 解决方案 > 在 Rust 中传递对结构的引用

问题描述

我的问题基本上是在我的程序中,我需要将对s结构的引用传递到多个地方,包括一个新线程。例如,在 CI 中可以将其声明为全局结构并以这种方式使用它。我怎么能在生锈中做到这一点?

我还需要对一些代码使用RefCell包装Rc(我以前的问题)。

fn a_thread(s: &SomeStruct) {

//... code using s reference ... //

}

struct SomeStruct {
    val: bool,
}

fn main() {
    let mut s = SomeStruct { val: true };

    let s_rc = Rc::new(RefCell::new(s));
    thread::spawn(move || a_thread(&s)); // <= error: use of moved value 's'
    
    
    //... code using the s_rc ... //
    

}



标签: structrustreferencerefcell

解决方案


如果一个线程修改数据而另一个线程读取它,则必须同步,否则您将遇到数据竞争。Safe Rust 通过静态分析防止数据竞争,因此它不会让您有一段&SomeStruct时间可以通过另一个线程修改底层值。

您可以做的是使用互斥锁而不是RefCell, 而Arc不是Rc

fn a_thread(s: Arc<Mutex<SomeStruct>) {
    // when you need data from s:
    {
        let s = s.lock().unwrap();
        // here you can read from s, or even obtain a `&SomeStruct`
        // but as long as you hold on to it, the main thread will be
        // blocked in its attempts to modify s
    }
}

fn main() {
    // create s on the heap
    let s = Arc::new(Mutex::new(SomeStruct { val: true }));

    // cloning the Arc creates another reference to the value
    let s2 = Arc::clone(&s);
    thread::spawn(move || a_thread(s2));
    
    //... code using s ... //
    {
        let s = s.lock().unwrap();
        // here you can modify s, but reading will be blocked
    }
}

推荐阅读