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 为什么可以';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

我应该如何根据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<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)
和impl
Send
。我假设API是一个单独的API,在单独的线程上同时使用是不安全的,这就是使用互斥+Arc的原因。谢谢@trentcl,我已经尝试将其纳入描述中。
unsafe impl Send for Api {}