从Rust线程和外部线程修改Arc <Mutex <T >>是否安全?

fgh*_*ghj 8 multithreading rust

是否有任何通用规则,设计文档或类似的东西解释了Rust标准库如何处理未生成的线程std::thread

我有一个cdylib箱子,并希望以螺纹方式从另一种语言中使用它:

use std::mem;
use std::sync::{Arc, Mutex};
use std::thread;

type jlong = usize;
type SharedData = Arc<Mutex<u32>>;

struct Foo {
    data: SharedData,
}

#[no_mangle]
pub fn Java_com_example_Foo_init(shared_data: &SharedData) -> jlong {
    let this = Box::into_raw(Box::new(Foo { data: shared_data.clone() }));
    this as jlong
}

#[cfg(target_pointer_width = "32")]
unsafe fn jlong_to_pointer<T>(val: jlong) -> *mut T {
    mem::transmute::<u32, *mut T>(val as u32)
}

#[cfg(target_pointer_width = "64")]
unsafe fn jlong_to_pointer<T>(val: jlong) -> *mut T {
    mem::transmute::<jlong, *mut T>(val)
}

#[no_mangle]
pub fn Java_com_example_Foo_f(this: jlong) {
    let mut this = unsafe { jlong_to_pointer::<Foo>(this).as_mut().unwrap() };
    let data = this.data.clone();
    let mut data = data.lock().unwrap();
    *data = *data + 5;
}
Run Code Online (Sandbox Code Playgroud)

特别是在

let shared_data = Arc::new(Mutex::new(5));
let foo = Java_com_example_Foo_init(&shared_data);
Run Code Online (Sandbox Code Playgroud)

是安全的修改shared_data从催生了一个线程thread::spawn,如果Java_com_example_Foo_f从一个未知的JVM线程调用?

它可能是坏的可能原因.

leo*_*228 1

是的。您链接的问题与librustrtRust 1.0 之前已删除的相关。RFC 230删除了librustrt,特别指出:

当将 Rust 代码嵌入到其他上下文中时——无论是从 C 代码调用还是嵌入高级语言——都需要进行大量设置来提供所依赖的“运行时”基础设施libstd。如果libstd改为绑定到本机线程和 I/O 系统,则嵌入设置会简单得多。

此外,请参阅实现该 RFC 的PR #19654 :

当在嵌入式上下文中使用 Rust 时,现在应该可以直接将 Rust 函数作为 C 函数调用,而无需任何设置,尽管在这种情况下,恐慌会导致进程中止。在这方面,C/Rust 接口看起来很像 C/C++ 接口。

对于当前文档,Rustonomicon 章节中关于 FFI的从 C 调用的 Rust 代码示例使用了libstdMutex我相信包括 ,尽管这是 的实现细节println!),而没有任何与运行时设置相关的警告。