在 Rust 中,我用什么来与多个线程和一个编写器共享一个对象? [英] What do I use to share an object with many threads and one writer in Rust?

查看:78
本文介绍了在 Rust 中,我用什么来与多个线程和一个编写器共享一个对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当对象有时可能由一个所有者写入时,在多个线程之间共享公共对象的正确方法是什么?

What is the right approach to share a common object between many threads when the object may sometimes be written to by one owner?

我尝试使用多种方法创建一个 Configuration 特征对象来获取和设置配置键.我想将它传递给可以读取配置项的其他线程.如果每个人都可以编写和阅读,那就加分了.

I tried to create one Configuration trait object with several methods to get and set config keys. I'd like to pass this to other threads where configuration items may be read. Bonus points would be if it can be written and read by everyone.

我发现了 一个 Reddit 线程,其中讨论了 RcRefCell;那是正确的方法吗?我认为这些不会允许我多次不变地借用对象并仍然对其进行变异.

I found a Reddit thread which talks about Rc and RefCell; would that be the right way? I think these would not allow me to borrow the object immutably multiple times and still mutate it.

推荐答案

Rust 有一个专门用于此任务的内置并发原语 RwLock.与 Arc 一起,它可以用来实现你想要的:

Rust has a built-in concurrency primitive exactly for this task called RwLock. Together with Arc, it can be used to implement what you want:

use std::sync::{Arc, RwLock};
use std::sync::mpsc;
use std::thread;

const N: usize = 12;

let shared_data = Arc::new(RwLock::new(Vec::new()));
let (finished_tx, finished_rx) = mpsc::channel();

for i in 0..N {
    let shared_data = shared_data.clone();
    let finished_tx = finished_tx.clone();
    if i % 4 == 0 {
        thread::spawn(move || {
            let mut guard = shared_data.write().expect("Unable to lock");
            guard.push(i);
            finished_tx.send(()).expect("Unable to send");
        });
    } else {
        thread::spawn(move || {
            let guard = shared_data.read().expect("Unable to lock");
            println!("From {}: {:?}", i, *guard);
            finished_tx.send(()).expect("Unable to send");
        });
    }
}

// wait until everything's done
for _ in 0..N {
    let _ = finished_rx.recv();
}

println!("Done");

这个例子很傻,但它演示了RwLock是什么以及如何使用它.

This example is very silly but it demonstrates what RwLock is and how to use it.

另请注意,RcRefCell/Cell 不适用于多线程环境,因为它们没有正确同步.Rust 甚至不允许你在 thread::spawn() 中使用它们.要在线程之间共享数据,您必须使用 Arc,并且要共享 可变 数据,您必须另外使用一种同步原语,例如 RWLock 或 <代码>互斥.

Also note that Rc and RefCell/Cell are not appropriate in a multithreaded environment because they are not synchronized properly. Rust won't even allow you to use them at all with thread::spawn(). To share data between threads you must use an Arc, and to share mutable data you must additionally use one of the synchronization primitives like RWLock or Mutex.

这篇关于在 Rust 中,我用什么来与多个线程和一个编写器共享一个对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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