pub struct SpinlockGuard<'a, T: ?Sized + 'a> { /* private fields */ }
Expand description
自旋锁的RAII Guard
RAII Guard 用于提供 Scoped Lock 机制。
SpinlockGuard
中包含Spinlock
的引用, 当SpinlockGuard
生命周期结束时,会在drop()
方法中自动解锁自旋锁。SpinlockGuard
不可在线程之间转移所有权,因为其drop()
方法包含解锁的语义,上锁和解锁必须在同一线程;SpinlockGuard
虽然可以在多线程中传递引用(Sync
约束),但其实现中没有 unlock() 方法,意味着其他线程即便拿到引用也不能解锁。
Implementations§
source§impl<'a, T: ?Sized> SpinlockGuard<'a, T>
impl<'a, T: ?Sized> SpinlockGuard<'a, T>
sourcepub fn wait(self, cond: &Cond) -> Result<SpinlockGuard<'a, T>, CondError>
pub fn wait(self, cond: &Cond) -> Result<SpinlockGuard<'a, T>, CondError>
阻塞当前线程,直到被条件量唤醒
此方法会消费自旋锁的守卫(Guard),并当线程阻塞时,在条件量内部释放自旋锁。 当条件成立,线程被唤醒,会在条件量内部上锁自旋锁,并重新返回自旋锁的守卫(Guard)。
- 当返回自旋锁的守卫
SpinlockGuard
时,自旋锁已经被重新上锁; - 当返回
Err
时,自旋锁未被上锁。
§参数说明
- cond: 条件量的引用
§错误码
CondError::NotInit
条件量未被初始化CondError::Interrupt
等待被中断CondError::NotThreadContext
不在线程上下文中
§示例
use xwrust::xwos::thd;
use xwrust::xwos::lock::spinlock::*;
use xwrust::xwos::sync::cond::*;
extern crate alloc;
use alloc::sync::Arc;
pub fn xwrust_example_spinlock() {
let pair = Arc::new((Spinlock::new(true), Cond::new()));
pair.1.init();
let pair_c = pair.clone();
thd::Builder::new()
.name("child".into())
.spawn(move |_| { // 子线程闭包
cthd::sleep(xwtm::ms(500));
let (lock, cvar) = &*pair_c;
let mut guard = lock_child.lock();
*guard = false; // 设置共享数据
drop(guard); // 先解锁再触发条件可提高效率
cvar.broadcast();
});
let (lock, cvar) = &*pair;
{
let mut guard = lock.lock();
while *guard {
match guard.wait(cvar) {
Ok(g) => { // 唤醒
guard = g; // 重新捕获守卫
},
Err(e) => { // 等待条件量失败
break;
},
}
}
}
}
sourcepub fn wait_to(
self,
cond: &Cond,
to: XwTm,
) -> Result<SpinlockGuard<'a, T>, CondError>
pub fn wait_to( self, cond: &Cond, to: XwTm, ) -> Result<SpinlockGuard<'a, T>, CondError>
限时阻塞当前线程,直到被条件量唤醒
此方法会消费自旋锁的守卫(Guard),并当线程阻塞时,在条件量内部释放自旋锁。 当条件成立,线程被唤醒,会在条件量内部上锁自旋锁,并重新返回自旋锁的守卫(Guard)。 当超时后,将返回错误。
- 当返回自旋锁的守卫
SpinlockGuard
时,自旋锁已经被重新上锁; - 当返回
Err
时,自旋锁未被上锁。
§参数说明
- cond: 条件量的引用
- to: 期望唤醒的时间点
§错误码
CondError::NotInit
条件量未被初始化CondError::Interrupt
等待被中断CondError::Timedout
等待超时CondError::NotThreadContext
不在线程上下文中
§示例
use xwrust::xwos::thd;
use xwrust::xwos::lock::spinlock::*;
use xwrust::xwos::sync::cond::*;
extern crate alloc;
use alloc::sync::Arc;
pub fn xwrust_example_spinlock() {
let pair = Arc::new((Spinlock::new(true), Cond::new()));
pair.1.init();
let pair_c = pair.clone();
thd::Builder::new()
.name("child".into())
.spawn(move |_| { // 子线程闭包
cthd::sleep(xwtm::ms(500));
let (lock, cvar) = &*pair_c;
let mut guard = lock_child.lock();
*guard = false; // 设置共享数据
drop(guard); // 先解锁再触发条件可提高效率
cvar.broadcast();
});
let (lock, cvar) = &*pair;
{
let mut guard = lock.lock();
while *guard {
match guard.wait_to(cvar, xwtm::ft(xwtm::s(2))) {
Ok(g) => { // 唤醒
guard = g; // 重新捕获守卫
},
Err(e) => { // 等待条件量失败
break;
},
}
}
}
}
sourcepub fn wait_unintr(self, cond: &Cond) -> Result<SpinlockGuard<'a, T>, CondError>
pub fn wait_unintr(self, cond: &Cond) -> Result<SpinlockGuard<'a, T>, CondError>
阻塞当前线程,直到被条件量唤醒,且阻塞不可被中断
此方法会消费自旋锁的守卫(Guard),并当线程阻塞时,在条件量内部释放自旋锁。 当条件成立,线程被唤醒,会在条件量内部上锁自旋锁,并重新返回自旋锁的守卫(Guard)。
- 当返回自旋锁的守卫
SpinlockGuard
时,自旋锁已经被重新上锁; - 当返回
Err
时,自旋锁未被上锁。
§参数说明
- cond: 条件量的引用
§错误码
CondError::NotInit
条件量未被初始化CondError::NotThreadContext
不在线程上下文中
§示例
use xwrust::xwos::thd;
use xwrust::xwos::lock::spinlock::*;
use xwrust::xwos::sync::cond::*;
extern crate alloc;
use alloc::sync::Arc;
pub fn xwrust_example_spinlock() {
let pair = Arc::new((Spinlock::new(true), Cond::new()));
pair.1.init();
let pair_c = pair.clone();
thd::Builder::new()
.name("child".into())
.spawn(move |_| { // 子线程闭包
cthd::sleep(xwtm::ms(500));
let (lock, cvar) = &*pair_c;
let mut guard = lock_child.lock();
*guard = false; // 设置共享数据
drop(guard); // 先解锁再触发条件可提高效率
cvar.broadcast();
});
let (lock, cvar) = &*pair;
{
let mut guard = lock.lock();
while *guard {
match guard.wait_unintr(cvar) {
Ok(g) => { // 唤醒
guard = g; // 重新捕获守卫
},
Err(e) => { // 等待条件量失败
break;
},
}
}
}
}