如何使用 Arc<Mutex<MyStruct<T>> 在线程之间共享通用结构? [英] How do I share a generic struct between threads using Arc&lt;Mutex&lt;MyStruct&lt;T&gt;&gt;&gt;?

查看:41
本文介绍了如何使用 Arc<Mutex<MyStruct<T>> 在线程之间共享通用结构?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些需要在线程之间共享的可变状态.我遵循了 Rust 书中的 并发部分,它在线程和线程之间共享一个向量改变它.

I have some mutable state I need to share between threads. I followed the concurrency section of the Rust book, which shares a vector between threads and mutates it.

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

Instead of a vector, I need to share a generic struct that is ultimately monomorphized. Here is a distilled example of what I'm trying:

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, and what the appropriate way to accomplish this is.

推荐答案

我试图理解为什么 M 需要实现 Send, ...

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

因为,正如 Send 文档 所述:

Because, as stated by the Send documentation:

可以跨线程边界传输的类型.

Types that can be transferred across thread boundaries.

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

If it's not Send, it is by definition not safe to send to another thread.

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

Almost all of the information you need is right there in the documentation:

  • thread::spawn 需要可调用的你让它成为Send.
  • 您正在使用闭包,如果它捕获的所有值都是 Send,则它仅是 Send.对于大多数类型而言,这通常是正确的(如果它们由 Send 组成,则它们是 Send,对于 Sync 也是如此).
  • 您正在捕获数据,这是一个Arc,如果TSend,则它只是Send.
  • T 是一个 Mutex,如果USend,它只是Send.
  • UM.因此,M 必须是 Send.
  • thread::spawn requires the callable you give it to be Send.
  • You're using a closure, which is only Send if all the values it captures are Send. This is true in general of most types (they are Send if everything they're made of is Send, and similarly for Sync).
  • You're capturing data, which is an Arc<T>, which is only Send if T is Send.
  • T is a Mutex<U>, which is only Send if U is Send.
  • U is M. Thus, M must be Send.

此外,请注意 thread::spawn 还要求可调用对象为 'static,因此您也需要这样做.它需要那个,因为如果它不需要那个,它就不能保证该值将在线程的整个生命周期内继续存在(这可能会也可能不会超过产生它).

In addition, note that thread::spawn also requires that the callable be 'static, so you need that too. It needs that because if it didn't require that, it'd have no guarantee that the value will continue to exist for the entire lifetime of the thread (which may or may not outlive the thread that spawned it).

...,以及实现此目的的适当方法是什么.

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

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

Same way as any other constraints: M: 'static + Send + Memory.

这篇关于如何使用 Arc<Mutex<MyStruct<T>> 在线程之间共享通用结构?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆