我需要在线程之间共享一些可变状态。我跟着Rust书的concurrency section,它在线程之间共享一个向量并改变它。
我需要共享最终单形化的通用结构,而不是向量。以下是我正在尝试的一个简单的例子:
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;
use std::marker::PhantomData;
trait Memory {}
struct SimpleMemory;
impl Memory for SimpleMemory {}
struct SharedData<M: Memory> {
value: usize,
phantom: PhantomData<M>,
}
impl<M: Memory> SharedData<M> {
fn new() -> Self {
SharedData {
value: 0,
phantom: PhantomData,
}
}
}
fn main() {
share(SimpleMemory);
}
fn share<M: Memory>(memory: M) {
let data = Arc::new(Mutex::new(SharedData::<M>::new()));
for i in 0..3 {
let data = data.clone();
thread::spawn(move || {
let mut data = data.lock().unwrap();
data.value += i;
});
}
thread::sleep(Duration::from_millis(50));
}
编译器抱怨以下错误:
error[E0277]: the trait bound `M: std::marker::Send` is not satisfied
--> src/main.rs:37:9
|
37 | thread::spawn(move || {
| ^^^^^^^^^^^^^
|
= help: consider adding a `where M: std::marker::Send` bound
= note: required because it appears within the type `std::marker::PhantomData<M>`
= note: required because it appears within the type `SharedData<M>`
= note: required because of the requirements on the impl of `std::marker::Send` for `std::sync::Mutex<SharedData<M>>`
= note: required because of the requirements on the impl of `std::marker::Send` for `std::sync::Arc<std::sync::Mutex<SharedData<M>>>`
= note: required because it appears within the type `[closure@src/main.rs:37:23: 40:10 data:std::sync::Arc<std::sync::Mutex<SharedData<M>>>, i:usize]`
= note: required by `std::thread::spawn`
我试图理解为什么M
需要实现Send
,以及实现此目的的恰当方法是什么。
答案 0 :(得分:8)
我试图理解为什么
M
需要实施Send
,...
可跨线程边界传输的类型。
如果它不是Send
,那么按照定义发送到另一个帖子是不安全的。
您需要的几乎所有信息都是文档中的 :
thread::spawn
要求您提供的密码为Send
。Send
,则只有Send
。大多数类型的情况都是如此(Send
如果他们所做的一切都是Send
,而Sync
则类似。data
Arc<T>
,如果Send
为T
,则Send
仅为T
。Send
是Mutex<U>
,如果U
为Send
,则仅U
。M
是M
。因此,Send
必须为thread::spawn
。此外,请注意'static
还要求可调用者为M: 'static + Send + Memory
,因此您也需要它。它需要那个因为如果它不需要它,它就不能保证该值在线程的整个生命周期内都会继续存在(这可能会或可能不会过时)产生它的线程。)
......,以及实现这一目标的适当方法是什么。
与任何其他约束相同:{{1}}。