在 Rust 中传递对结构的引用
Passing around a reference to a struct in Rust
我的问题基本上是在我的程序中我需要将对 s
结构的引用传递到多个地方,包括一个新线程。例如,在 C 中,我可以将其声明为全局结构并以这种方式使用它。
我怎样才能在生锈中做到这一点?
我还需要使用包裹在 Rc
中的 RefCell
用于某些代码(我之前的问题)。
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 ... //
}
如果一个线程修改数据而另一个线程读取数据,则必须进行同步,否则就会发生数据竞争。 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
}
}
我的问题基本上是在我的程序中我需要将对 s
结构的引用传递到多个地方,包括一个新线程。例如,在 C 中,我可以将其声明为全局结构并以这种方式使用它。
我怎样才能在生锈中做到这一点?
我还需要使用包裹在 Rc
中的 RefCell
用于某些代码(我之前的问题)。
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 ... //
}
如果一个线程修改数据而另一个线程读取数据,则必须进行同步,否则就会发生数据竞争。 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
}
}