gpt4 book ai didi

rust - 可以是 `Send` 的 RefCell 替代方案?

转载 作者:行者123 更新时间:2023-12-04 14:06:34 25 4
gpt4 key购买 nike

我正在设计一种可以在线程之间发送或不发送的类型,这取决于它是否是拥有的类型。
这段代码:

use std::cell::RefCell;
use std::rc::Rc;

pub enum M<'a, T> {
Owned(),
Ref(Rc<RefCell<&'a mut [T]>>)
}

fn main() {
let m: M<'static, u8> = M::Owned();
std::thread::spawn(||{
let m = m;
});
}
error[E0277]: `Rc<RefCell<&mut [_]>>` cannot be sent between threads safely
--> src/main.rs:11:5
|
11 | std::thread::spawn(||{
| _____^^^^^^^^^^^^^^^^^^_-
| | |
| | `Rc<RefCell<&mut [_]>>` cannot be sent between threads safely
12 | | let m = m;
13 | | });
| |_____- within this `[closure@src/main.rs:11:24: 13:6]`
我知道这不是 Send因为 RefCell!Send .我认为这是唯一阻止 M 的原因来自 Send .有没有 RefCell替代方案是 Send ?

最佳答案

I understand that this is not Send because RefCell is !Send. I think this is the only thing preventing M from being Send.


是的,这是正确的。

Is there a RefCell alternative that is Send?


当然,至少有两个。如果您只想要 &mut在另一个线程中,您实际上可以发送它:
#[derive(Debug)]
pub enum M<'a, T> {
Owned(),
Ref(&'a mut [T])
}

fn main() {
let m: M<'static, u8> = M::Owned();
std::thread::spawn(move ||{
println!("{:?}", m);
}).join().unwrap();
}
但是如果你使用 Rc<RefCell<_>>例如让您的 &mut可共享,您可以使用 Arc<Mutex<_>> 在多线程上下文中实现相同的功能,正如@Locke 已经提到的:
use std::sync::{Arc, Mutex};

#[derive(Debug, Clone)]
pub enum M<'a, T> {
Owned(),
Ref(Arc<Mutex<&'a mut [T]>>)
}

fn main() {
let m: M<'static, u8> = M::Owned();
let m2 = m.clone();
std::thread::spawn(move ||{
println!("{:?}", m2);
}).join().unwrap();
println!("{:?}", m);
}

关于rust - 可以是 `Send` 的 RefCell 替代方案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68241145/

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