RwLock 何时会发生 panic 而非死锁?

7
我注意到有时Rust会因为死锁而出现panic。 例如,以下代码会导致panic:
let rw_lock = RwLock::new(42);
{
    let data0 = rw_lock.write().unwrap();
    let data1 = rw_lock.read().unwrap();
    let data2 = rw_lock.read().unwrap();
}

然而,这样做并不会成功(反而会导致死锁):
let rw_lock = RwLock::new(42);
{
    let data1 = rw_lock.read().unwrap();
    let data2 = rw_lock.read().unwrap();
    let data3 = rw_lock.write().unwrap();
}

什么情况下Rust会发生panic而不是死锁?为什么会这样?

1
注意:即使没有 .unwrap() 调用,这个程序也会 panic,因此它确实在死锁时 panic(而不仅仅是返回错误)。 - bluss
1个回答

7
根据实现,该技术与IT相关。
// According to the pthread_rwlock_rdlock spec, this function **may**
// fail with EDEADLK if a deadlock is detected. On the other hand
// pthread mutexes will *never* return EDEADLK if they are initialized
// as the "fast" kind (which ours always are). As a result, a deadlock
// situation may actually return from the call to pthread_rwlock_rdlock
// instead of blocking forever (as mutexes and Windows rwlocks do). Note
// that not all unix implementations, however, will return EDEADLK for
// their rwlocks.
//
// We roughly maintain the deadlocking behavior by panicking to ensure
// that this lock acquisition does not succeed.

请注意,此注释仅适用于UNIX版本的RwLock实现,Windows实现可能存在差异。事实上,它没有任何panic!语句。
猜测一下,我认为这只是一种尽力报道常见错误情况的尝试,不能依赖它作为任何官方信息。

1
而 Rust 语言没有保证这一点的原因可能是这会过度限制某些平台,从而牺牲性能。 - Matthieu M.
@MatthieuM。听起来非常合理。Rust 在这里似乎只是讲现有的实现包装起来,而不是重新编写所有那些困难的代码。设计师们可能必须在“有用性”和“最低公共分母”之间保持平衡。 - Shepmaster

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接