为什么使用 Condvar 等待和通知不会死锁?
Why does this use of Condvar wait and notify not deadlock?
https://doc.rust-lang.org/stable/std/sync/struct.Condvar.html
use std::sync::{Arc, Mutex, Condvar};
use std::thread;
let pair = Arc::new((Mutex::new(false), Condvar::new()));
let pair2 = Arc::clone(&pair);
// Inside of our lock, spawn a new thread, and then wait for it to start.
thread::spawn(move|| {
let (lock, cvar) = &*pair2;
let mut started = lock.lock().unwrap(); // #1
*started = true;
// We notify the condvar that the value has changed.
cvar.notify_one();
});
// Wait for the thread to start up.
let (lock, cvar) = &*pair;
let mut started = lock.lock().unwrap(); // #2
while !*started {
started = cvar.wait(started).unwrap();
}
如果我理解正确,衍生线程 (#1
) 中的核心可能 运行 在主线程锁定互斥锁 (#2
) 之后。但是在这种情况下,主线程永远不会解锁它,因为派生线程无法锁定它并更改值,所以循环永远保持 运行ning ... 或者,是因为某些 Condvar
机械师?
wait
's documentation 说(强调):
pub fn wait<'a, T>(
&self,
guard: MutexGuard<'a, T>
) -> LockResult<MutexGuard<'a, T>>
This function will atomically unlock the mutex specified (represented by guard
) and block the current thread. This means that any calls to notify_one
or notify_all
which happen logically after the mutex is unlocked are candidates to wake this thread up. When this function call returns, the lock specified will have been re-acquired.
当您在循环内调用 cvar.wait
时,它会解锁互斥量,这允许生成的线程锁定它并将 started
设置为 true
。
https://doc.rust-lang.org/stable/std/sync/struct.Condvar.html
use std::sync::{Arc, Mutex, Condvar};
use std::thread;
let pair = Arc::new((Mutex::new(false), Condvar::new()));
let pair2 = Arc::clone(&pair);
// Inside of our lock, spawn a new thread, and then wait for it to start.
thread::spawn(move|| {
let (lock, cvar) = &*pair2;
let mut started = lock.lock().unwrap(); // #1
*started = true;
// We notify the condvar that the value has changed.
cvar.notify_one();
});
// Wait for the thread to start up.
let (lock, cvar) = &*pair;
let mut started = lock.lock().unwrap(); // #2
while !*started {
started = cvar.wait(started).unwrap();
}
如果我理解正确,衍生线程 (#1
) 中的核心可能 运行 在主线程锁定互斥锁 (#2
) 之后。但是在这种情况下,主线程永远不会解锁它,因为派生线程无法锁定它并更改值,所以循环永远保持 运行ning ... 或者,是因为某些 Condvar
机械师?
wait
's documentation 说(强调):
pub fn wait<'a, T>( &self, guard: MutexGuard<'a, T> ) -> LockResult<MutexGuard<'a, T>>
This function will atomically unlock the mutex specified (represented by
guard
) and block the current thread. This means that any calls tonotify_one
ornotify_all
which happen logically after the mutex is unlocked are candidates to wake this thread up. When this function call returns, the lock specified will have been re-acquired.
当您在循环内调用 cvar.wait
时,它会解锁互斥量,这允许生成的线程锁定它并将 started
设置为 true
。