rust - 如何在rust中的多个线程上传递具有特征的数据结构?

标签 rust

这个问题在这里已经有了答案:





Sharing a struct with trait objects as properties across threads

(1 个回答)



Sending trait objects between threads in Rust

(1 个回答)


2年前关闭。




我正在尝试存储我的应用程序的状态,其中包括在开始时初始化并在多个线程之间传递状态的特征列表,但我收到错误。

use std::sync::{Arc, RwLock};
use std::thread;
use std::time::Duration;

trait TestTrait {
    fn test(&self);
}

struct MyTestStruct {}

impl TestTrait for MyTestStruct {
    fn test(&self) {
        println!("Test trait called");
    }
}

struct DataStore {
    t: Box<dyn TestTrait>,
}

fn main() {
    let s = Arc::new(RwLock::new(DataStore {
        t: Box::new(MyTestStruct {}),
    }));
    let s_clone = s.clone();
    thread::spawn(move || {
        for i in 1..10 {
            s_clone.read().unwrap().t.test();
            println!("hi number {} from the spawned thread!", i);
            thread::sleep(Duration::from_millis(1));
        }
    });

    for i in 1..5 {
        println!("hi number {} from the main thread!", i);
        thread::sleep(Duration::from_millis(1));
    }
}

当我运行它时,我收到以下错误:

error[E0277]: `(dyn TestTrait + 'static)` cannot be sent between threads safely
   --> src/main.rs:26:5
    |
26  |     thread::spawn(move || {
    |     ^^^^^^^^^^^^^ `(dyn TestTrait + 'static)` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `(dyn TestTrait + 'static)`
    = note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<(dyn TestTrait + 'static)>`
    = note: required because it appears within the type `std::boxed::Box<(dyn TestTrait + 'static)>`
    = note: required because it appears within the type `DataStore`
    = note: required because of the requirements on the impl of `std::marker::Send` for `std::sync::RwLock<DataStore>`
    = note: required because of the requirements on the impl of `std::marker::Send` for `std::sync::Arc<std::sync::RwLock<DataStore>>`
    = note: required because it appears within the type `[closure@src/main.rs:26:19: 32:6 s_clone:std::sync::Arc<std::sync::RwLock<DataStore>>]`

error[E0277]: `(dyn TestTrait + 'static)` cannot be shared between threads safely
   --> src/main.rs:26:5
    |
26  |     thread::spawn(move || {
    |     ^^^^^^^^^^^^^ `(dyn TestTrait + 'static)` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `(dyn TestTrait + 'static)`
    = note: required because of the requirements on the impl of `std::marker::Sync` for `std::ptr::Unique<(dyn TestTrait + 'static)>`
    = note: required because it appears within the type `std::boxed::Box<(dyn TestTrait + 'static)>`
    = note: required because it appears within the type `DataStore`
    = note: required because of the requirements on the impl of `std::marker::Sync` for `std::sync::RwLock<DataStore>`
    = note: required because of the requirements on the impl of `std::marker::Send` for `std::sync::Arc<std::sync::RwLock<DataStore>>`
    = note: required because it appears within the type `[closure@src/main.rs:26:19: 32:6 s_clone:std::sync::Arc<std::sync::RwLock<DataStore>>]`

我该如何解决?

最佳答案

thread::spawn 需要一个实现 Send 的闭包. Arc<T> 仅实现 Send如果 T实现SendSync .
SendSyncauto traits .您可以将自动特征添加到 dyn Trait type 以提供有关已删除类型的更多信息:

struct DataStore {
    t: Box<dyn TestTrait + Send + Sync>,
}

如果你要写dyn TestTrait + Send + Sync到处都是,那么另一种选择是声明SendSync作为 TestTrait 的超特征:
trait TestTrait: Send + Sync {
    fn test(&self);
}

关于rust - 如何在rust中的多个线程上传递具有特征的数据结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60594685/

相关文章:

generics - 我如何通用化 Yew Web 请求

utf-8 - Rust UTF-8 错误,线程 'main' 在 'called ` Result::unwrap() 处 panic

postgresql - 在 rust-postgres 中使用固定精度数字的正确方法是什么?

performance - 加速计数器游戏

rust - Cargo 功能是否可以启用可选依赖项中的功能而不强制激活这些 crate ?

r - 将 R 对象传递给 Rust 程序需要哪些步骤?

rust - 为什么使用 "Self"作为参数类型会引发生命周期错误?

rust - 有没有办法查看我的项目中所有依赖于另一个 crate 的 crate ?

vector - 如何访问新类型的向量作为基础类型

rust - 处理拒绝时获取当前路径