Rust 为什么可以';t我发送互斥锁<*mut c_void>;在线程之间? 我需要在C++线程之间共享一个C++创建的对象。我已经将它包装在一个互斥体结构中,因此现在可以在线程之间安全地发送它。但是编译器不让我做什么 错误[E0277]:`mut std::ffi::c_void`无法在线程之间安全发送 -->sendsync.rs:14:2 | 14 |线程::繁殖(移动| |){ |^^^^^^^^^^`*无法在线程之间安全地发送mut std::ffi::c_void` | =帮助:在'Api'中,'*mut std::ffi::c_void'未实现特性'std::marker::Send'` =注意:必需,因为它出现在“OpaqWrapper”类型中` =注意:必需,因为它出现在“Api”类型中` =注意:由于对`std::sync::Mutex`的`std::marker::Send` impl的要求,因此需要此选项` =注意:由于'std::marker::Send'的impl中对'std::sync::Arc'的要求,因此需要` =注意:必需,因为它出现在类型中`[closure@sendsync.rs:14:16:19:3安全\u对象:标准::同步::弧]`
我应该如何根据Rust规则实现这一点?以下是代码:Rust 为什么可以';t我发送互斥锁<*mut c_void>;在线程之间? 我需要在C++线程之间共享一个C++创建的对象。我已经将它包装在一个互斥体结构中,因此现在可以在线程之间安全地发送它。但是编译器不让我做什么 错误[E0277]:`mut std::ffi::c_void`无法在线程之间安全发送 -->sendsync.rs:14:2 | 14 |线程::繁殖(移动| |){ |^^^^^^^^^^`*无法在线程之间安全地发送mut std::ffi::c_void` | =帮助:在'Api'中,'*mut std::ffi::c_void'未实现特性'std::marker::Send'` =注意:必需,因为它出现在“OpaqWrapper”类型中` =注意:必需,因为它出现在“Api”类型中` =注意:由于对`std::sync::Mutex`的`std::marker::Send` impl的要求,因此需要此选项` =注意:由于'std::marker::Send'的impl中对'std::sync::Arc'的要求,因此需要` =注意:必需,因为它出现在类型中`[closure@sendsync.rs:14:16:19:3安全\u对象:标准::同步::弧]`,rust,Rust,我应该如何根据Rust规则实现这一点?以下是代码: use std::{ sync::{ Arc,Mutex, }, ptr, thread::{self}, }; pub struct OpaqWrapper { pub obj_ptr: *mut ::std::os::raw::c_void, } pub struct Api(OpaqWrapper); fn spawn_api_thread(safe_obj: Arc<Mut
use std::{
sync::{
Arc,Mutex,
},
ptr,
thread::{self},
};
pub struct OpaqWrapper {
pub obj_ptr: *mut ::std::os::raw::c_void,
}
pub struct Api(OpaqWrapper);
fn spawn_api_thread(safe_obj: Arc<Mutex<Api>>) {
thread::spawn(move || {
{
let my_api = safe_obj.lock().unwrap();
// my_api.whatever();
}
});
}
fn main() {
let api = Api(
OpaqWrapper {
obj_ptr: ptr::null_mut(),
}
);
let shared_api= Arc::new(Mutex::new(api));
for _ in 0..10 {
spawn_api_thread(shared_api.clone());
}
}
使用std::{
同步::{
弧,互斥体,
},
ptr,
线程::{self},
};
pub结构OpaqWrapper{
发布对象:mut::std::os::raw::c_void,
}
pub结构Api(OpaqWrapper);
fn生成api线程(安全对象:Arc){
线程::生成(移动| |{
{
让我的api=safe\u obj.lock().unwrap();
//我的api.whatever();
}
});
}
fn main(){
设api=api(
蛋白石包装{
obj_ptr:ptr::null_mut(),
}
);
让shared_api=Arc::new(Mutex::new(api));
对于0..10中的uu{
生成api线程(共享api.clone());
}
}
Short版本
将某物传递给线程需要它是Send
T:Send => Mutex<T>:Send+Sync => Arc<Mutex<T>>:Send
unsafe impl Send for Api {}
但是,Mutex
只需要Send
就可以同时是Sync
和Send
,其代码包含:
unsafe impl<T: ?Sized + Send> Send for Mutex<T> { }
unsafe impl<T: ?Sized + Send> Sync for Mutex<T> { }
注意,您不需要将它们标记为
Sync
,因为Mutex
会自动获取它们。如果您确定OpaqWrapper
中的指针是所有的,那么您可以在OpaqWrapper
上手动实现Send
。Mutex
也是如此:实际上,Mutex
都是Se当T
仅为Send
时,nd
和Sync
。这就是为什么Api
不需要Sync
。并且这些都不需要Mutex
或Arc
(在这种情况下,它们可能都是错误的)。您只需执行struct Foo(*mut Bar)
和implSend
。我假设API是一个单独的API,在单独的线程上同时使用是不安全的,这就是使用互斥+Arc的原因。谢谢@trentcl,我已经尝试将其纳入描述中。
unsafe impl Send for Api {}