中毒(Poisoning)

尽管所有不安全代码 必须(must) 确保其具有最小的异常安全性,但并非所有类型都能确保 最大的(maximal)* 异常安全性.即使类型确实存在,你的代码也可能会赋予其附加含义.例如,一个整数当然是异常安全的,但它本身没有语义.恐慌的代码可能无法正确更新整数,从而产生不一致的程序状态.

通常(usually) 很好,因为任何见证异常的东西都将被摧毁.例如,如果你将Vec发送到另一个线程并且该线程发生恐慌,那么Vec是否处于奇怪状态并不重要.它将被删除并永远消失.然而,有些类型特别擅长跨越恐慌边界的走私值.

如果他们目睹恐慌,这些类型可能会选择显式地 毒害(poison) 自己.中毒并不特别需要任何东西.通常它只是意味着阻止正常使用继续进行.最值得注意的例子是标准库的Mutex类型.如果其中一个MutexGuards(在获得锁定时返回的东西)在恐慌期间被删除,则互斥锁(Mutex)将自行中毒.任何未来锁定互斥锁的尝试都将返回Err或恐慌.

在Rust通常关心的意义上,互斥锁中毒并不是真正的安全.它作为一种安全防范措施,可以盲目地使用Mutex发出的数据,该数据在锁定时目睹恐慌.这种互斥锁中的数据很可能正在被修改,因此可能处于不一致或不完整的状态.重要的是要注意,如果正确写入,则不能违反这种类型的存储器安全性.毕竟,它必须是最低限度的例外安全!

但是,如果Mutex包含一个实际上没有堆属性的BinaryHeap,那么使用它的任何代码都不可能完成作者的意图.因此,该程序不应该正常进行.尽管如此,如果你确定(double-plus-sure)可以对该值执行 某些(something) 操作,那么Mutex会公开一种获取锁定的方法.毕竟,它 是(is) 安全的.可能是胡说八道.