gpt4 book ai didi

rust - 如何使用 Arc>> 在线程之间共享通用结构?

转载 作者:行者123 更新时间:2023-11-29 07:56:41 27 4
gpt4 key购买 nike

我有一些可变状态需要在线程之间共享。我关注了concurrency section Rust 书的一部分,它在线程之间共享一个向量并对其进行变异。

我需要共享一个最终单态化的通用结构,而不是向量。这是我正在尝试的一个精炼示例:

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,以及实现它的合适方法是什么。

最佳答案

I'm trying to understand why M would need to implement Send, ...

因为,如 the Send documentation 所述:

Types that can be transferred across thread boundaries.

如果不是 Send根据定义发送到另一个线程是不安全的。

您需要的几乎所有信息都就在文档中:

  • thread::spawn 要求你给它的 callable 是 Send .
  • 你正在使用一个闭包,它只是 Send如果它捕获的所有值都是 Send .大多数类型都是如此(它们是 Send 如果它们的所有组成部分都是 Send ,对于 Sync 也是如此)。
  • 您正在捕获 data ,这是一个 Arc<T> , 这只是 Send如果TSend .
  • T Mutex<U> , 这只是 Send如果USend .
  • UM .因此,M必须是 Send .

此外,请注意 thread::spawn还要求可调用对象为 'static ,所以你也需要它。它需要那个,因为如果它不需要那个,它就无法保证该值将在线程的整个生命周期内继续存在(它可能会或可能不会比产生的线程长寿它)。

..., and what the appropriate way to accomplish this is.

与任何其他约束的方式相同:M: 'static + Send + Memory .

关于rust - 如何使用 Arc<Mutex<MyStruct<T>>> 在线程之间共享通用结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40035731/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com