futures::lock::Mutex
没有实现RefUnwindSafe
的特性(见https://docs.rs/futures/0.3.17/futures/lock/struct.Mutex.html#impl-RefUnwindSafe)
为什么在std::panic::catch_unwind
中通过futures::lock::Mutex
不安全?
复制代码:
use std::panic::catch_unwind;
use futures::lock::Mutex;
fn main() {
let m = Mutex::new(String::new());
catch_unwind(|| {
m.lock()
});
}
futures::lock::Mutex
可以实现RefUnwindSafe
的特性吗?
UnwindSafe
特性的文档暗示了这样做的原因:
谁实现了UnwindSafe?
类型,如&mut和&RefCell是不unwind安全的例子。一般的想法是,任何可以在catch_unwind之间共享的可变状态在默认情况下都不是unwind安全的。这是因为在catch_unwind之外很容易看到一个被破坏的不变量,因为数据只是像往常一样被访问。
然而,像&Mutex这样的类型是unwind安全的,因为它们在默认情况下实现了中毒。它们仍然允许见证一个被破坏的不变量,但它们已经提供了自己的"减速带"来做到这一点。
futures::lock::Mutex
提供了像&mut T
和RefCell<T>
一样的可变性,但不实现std::sync::Mutex<T>
的中毒特性,因此不实现UnwindSafe
。
尽管正如文档所指出的,UnwindSafe
不是关于内存安全的,而是关于维护逻辑不变量的——这就是为什么UnwindSafe
和AssertUnwindSafe
都不是unsafe
的原因。