Rust 停车场文件上写着';允许在没有RAII保护对象的情况下原始(取消)锁定';?
他们说:Rust 停车场文件上写着';允许在没有RAII保护对象的情况下原始(取消)锁定';?,rust,mutex,raii,Rust,Mutex,Raii,他们说: Mutex和RwLock允许在没有RAII保护对象的情况下进行原始解锁 Mutex和RwLock允许在没有RAII保护对象的情况下进行原始锁定 没有进一步提到这些特性,它们的含义以及如何使用它们。一些指针或示例使用了什么?Rust保证安全代码不会包含数据竞争(对同一对象的并发可变访问)。互斥锁允许线程对对象进行互斥的读/写访问,从而避免了竞争 在其他语言中,(java和C++出现)互斥体与数据没有明确的关联。由程序员来确保他们正确地锁定和解锁它们,只访问锁定和解锁之间的关键部分内的数据
Mutex
和RwLock
允许在没有RAII保护对象的情况下进行原始解锁Mutex
和RwLock
允许在没有RAII保护对象的情况下进行原始锁定没有进一步提到这些特性,它们的含义以及如何使用它们。一些指针或示例使用了什么?Rust保证安全代码不会包含数据竞争(对同一对象的并发可变访问)。互斥锁允许线程对对象进行互斥的读/写访问,从而避免了竞争 在其他语言中,(java和C++出现)互斥体与数据没有明确的关联。由程序员来确保他们正确地锁定和解锁它们,只访问锁定和解锁之间的关键部分内的数据。在Rust中,这意味着如果编写错误,安全代码可能包含数据竞争 解决这个问题的办法是使用RAII防护装置。互斥体“拥有”关联的对象,只允许通过代表互斥体锁的RAII保护进行读/写访问。这是std返回的
MutexGuard
类型
Parking_lot声称允许在不创建RAII防护的情况下进行锁定/解锁,这在编写不安全代码时非常有用,因为速度原因,它可以使用互斥锁执行奇特的操作。这与std的sync::Mutex
不同,后者不提供这些方法
RAII防护的主要限制是,根据RAII的性质,它们只能维持封闭范围内的时间。此外,它们持有对互斥体的引用,因此由于Rust的借用规则,“存储”超过其作用域的“锁”是很困难的
参考的停车场方法是不安全的
raw\u解锁
和安全的raw\u锁
。由于raw\u lock()
需要关联的raw\u unlock()
来完成关键部分,因此使用这些功能意味着深入研究不安全的代码,除非您有充分的理由相信这是实现所需的唯一方法,否则这通常是不明智和不必要的。互斥体API通过一个防护装置控制对其数据的访问,该防护装置在超出范围时解锁互斥体。Mutex
拥有自己的数据,并且可以强制规定只有在锁定时才能通过MutexGuard
访问数据。std::sync::Mutex
和停车场::Mutex
在这方面是相同的
但是,parking\u lot::Mutex
也公开了它的内部结构,即指向数据的原始指针和RawMutex
。RawMutex
只是一个锁,它不控制对数据的访问,只跟踪锁的状态
使用RawMutex
的一个原因可能是,在范围内保留MutexGuard
非常不方便,并且您准备自己管理锁状态的时候。这更可能是在定义新同步原语或智能指针的库中,而不是在应用程序代码中,但是如果您机械地将现有的C/C++代码转换为Rust,您也可能会发现它很有用
举一个简单的例子,这些函数彼此做相同的事情,但其中一个使用不安全的RawMutex
:
use parking_lot::{Mutex, lock_api::RawMutex as _};
fn update_mutex(mutex: &Mutex<i32>) {
let mut guard = mutex.lock();
*guard = 2;
// guard goes out of scope here, causing the Mutex to be unlocked
}
fn update_mutex_raw(mutex: &Mutex<i32>) {
let raw_mutex = unsafe { mutex.raw() };
let data = mutex.data_ptr();
raw_mutex.lock();
unsafe {
*data = 2;
// need to manually unlock the RawMutex
raw_mutex.unlock();
};
}
使用停车场::{Mutex,lock_api::RawMutex as};
fn更新\u互斥体(互斥体:&互斥体){
让mut-guard=mutex.lock();
*防护罩=2;
//guard在此超出范围,导致互斥锁被解锁
}
fn更新\u互斥体\u原始(互斥体:&互斥体){
让raw_mutex=unsafe{mutex.raw()};
让data=mutex.data_ptr();
raw_mutex.lock();
不安全{
*数据=2;
//需要手动解锁RawMutex
raw_mutex.unlock();
};
}
RawMutex.unlock()
是不安全的,因为当murex未锁定时,它会触发调用它的未定义行为。同时两次取消对数据指针的引用也是未定义的行为,因此您可以通过遵守RawMutex
的锁定状态来确保您没有这样做
与往常一样,在使用不安全的函数时,请仔细阅读文档,并确保您彻底理解了为避免未定义的行为而必须保留的不变量。可能指的是不安全的和安全的,后者仅在
Mutex
上可用。如果停车场的Mutex
和RawMutex
之间有任何性能差异,我会非常惊讶。同意。它不会在单个操作中产生性能差异,而是通过在与单个RAII guard不兼容的模式中锁定和解锁,从而减少锁定和解锁的数量或保留某些其他属性。