为何以下Mutex无法被多线程共享?Rust编译错误排查
Rust线程安全错误分析与解决
Rust代码实现
pub fn with_lock<T>(f: &dyn Fn(&mut Connection) -> T) -> T { let mut guard = Connection::mutex().lock().unwrap(); let re = f(&mut *guard); re } pub fn start() -> Result<()> { let fusion = Arc::new(any_fusion()?); let fusion_clone = Arc::clone(&fusion); let fusion_m = Mutex::new(fusion_clone); let handle = thread::spawn(|| { // Task to be executed in the new thread loop { fusion_m.lock().unwrap().update(); } }); Self::with_lock(&|c| { c.fusion = Some(*fusion); c.thread = Some(handle); }); Ok(()) }
编译错误信息
error[E0277]: `dyn Fusion` cannot be shared between threads safely --> src/lib.rs:189:36 | 189 | let handle = thread::spawn(|| { | ______________________-------------_^ | | | | | required by a bound introduced by this call 190 | | // Task to be executed in the new thread 191 | | loop { 192 | | fusion_m.lock().unwrap().update(); 193 | | } 194 | | }); | |_________^ `dyn Fusion` cannot be shared between threads safely | = help: the trait `Sync` is not implemented for `dyn Fusion` = note: required for `Unique<dyn Fusion>` to implement `Sync`
问题原因
你觉得Mutex<Arc<dyn Fusion>>应该线程安全,但忽略了Rust对trait对象的线程安全约束:
Arc<T>要实现Send和Sync,要求内部的T必须同时满足Send trait和Sync trait——因为Arc是线程安全的引用计数容器,允许跨线程共享和转移所有权。- 这里的
T是dyn Fusion,默认情况下trait对象不会自动继承Send和Sync,除非Fusiontrait本身标注了这些超级约束,或者创建trait对象时明确附加这些约束。 - 错误提示里的
Unique<dyn Fusion>是Arc内部管理内存的类型,它需要dyn Fusion实现Sync才能满足线程安全,而当前dyn Fusion没有这个实现,导致Arc<dyn Fusion>不满足线程安全要求,进而Mutex<Arc<dyn Fusion>>无法被安全地move到新线程的闭包中(thread::spawn要求闭包实现Send)。
解决方案
有两种可行的修复方式:
方式一:给Fusion trait添加Send + Sync超级约束
在定义Fusion trait时,直接把Send和Sync作为超级trait,这样所有实现该trait的类型都会自动继承线程安全约束:
trait Fusion: Send + Sync { fn update(&self); // 其他方法定义... }
方式二:创建trait对象时明确指定Send + Sync约束
如果无法修改Fusion trait的定义,可以在创建Arc时,给trait对象附加Send + Sync约束:
// 修改start函数中的fusion创建语句 let fusion = Arc::new(any_fusion()? as dyn Fusion + Send + Sync); let fusion_clone = Arc::clone(&fusion);
这样Arc<dyn Fusion + Send + Sync>会自动实现Send和Sync,Mutex包裹它之后就能满足线程安全要求,闭包也能被thread::spawn正常接受。
内容的提问来源于stack exchange,提问作者tribbloid
相关产品推荐
相关产品推荐

