Expand description
§XWOS RUST:信号量
信号量是操作系统比较底层的同步机制,可以同时阻塞一个或多个线程。
信号量中包含一个整数值,当信号量的值大于等于0时,信号量可以唤醒一个正在等待的线程。线程被唤醒时会取走一个值,信号量的值减少1。
任意上下文都可增加信号量的值,这个操作被称为 发布 。
信号量常常用于在中断中唤醒一个线程,并将耗时较长的操作放在线程中执行。可减少中断上下文的执行时间,增加中断吞吐量,降低中断延迟。
§创建
XWOS RUST的信号量可使用 Sem::new()
创建。
- 可以创建具有静态生命周期
static
约束的全局变量:
use xwrust::xwos::sync::sem::*;
static GLOBAL_SEM: Sem = Sem::new();
- 也可以使用
alloc::sync::Arc
在heap中创建:
extern crate alloc;
use alloc::sync::Arc;
use xwrust::xwos::sync::sem::*;
pub fn xwrust_example_sem() {
let sem = Arc::new(Sem::new());
}
§初始化
无论以何种方式创建的信号量,都必须在使用前调用 Sem::init()
进行初始化:
pub fn xwrust_example_sem() {
GLOBAL_SEM.init(0, XwSsq::MAX);
sem.init(0, XwSsq::MAX);
}
§发布信号量
Sem::post()
方法可用来增加信号量的值。此方法可在 任意 上下文使用。
当信号量的值大与0时,会唤醒信号量等待队列中的一个线程。被唤醒的线程会取走一个值,使得信号量的计数器减1。
§获取信号量
当信号量的值大于 0 时,可以直接取走一个,此时信号量的值减 1 ; 当信号量的值等于 0 时,获取信号量的线程就只能阻塞等待,XWOS提供四种方式:
§等待并获取信号量
Sem::wait()
方法可用于等待并获取信号量:
- 若信号量的值小于等于0,线程会阻塞等待。
- 当信号量的值大于0时,线程被唤醒,并取走一个值(信号量的值减少1),然后返回
SemError::Ok
。 - 当线程阻塞等待被中断时,返回
SemError::Interrupt
。
§限时等待并获取信号量
Sem::wait_to()
方法可用来限时等待并获取信号量:
- 若信号量的值小于等于0,线程会阻塞等待,等待时会指定一个唤醒时间点。
- 当信号量的值大于0时,线程被唤醒,并取走一个值(信号量的值减少1),然后返回
SemError::Ok
。 - 当线程阻塞等待被中断时,返回
SemError::Interrupt
。 - 当到达指定的唤醒时间点,线程被唤醒,并返回
SemError::Timedout
。
§不可中断等待并获取信号量
Sem::wait_unintr()
方法可用来不可中断等待并获取信号量:
- 若信号量的值小于等于0,线程会阻塞等待,且不可被中断,也不会超时。
- 当信号量的值大于0时,线程被唤醒,并取走一个值(信号量的值减少1),然后返回
SemError::Ok
。
§尝试获取信号量
Sem::trywait()
方法可用来尝试获取信号量:
- 当信号量的值大于0时,就取走一个值(信号量的值减少1),然后返回
SemError::Ok
。 - 当信号量的值小于等于0时,立即返回
SemError::NoData
。
§冻结与解冻
§冻结
XWOS RUST的信号量可以使用方法 Sem::freeze()
进行 冻结 操作,被冻结的信号量的值为负数,不影响对信号量的 等待 操作。
但不能发布信号量。
§解冻
可以通过 Sem::thaw()
方法将已经冻结的信号量 解冻,信号量 解冻 后,值被重置为0,此时可重新开始发布信号量。
§获取信号量的最大值
可以通过方法 Sem::get_max()
获取信号量的最大值。
§获取信号量的值
可以通过方法 Sem::get_value()
获取信号量的值,此方法只是读取值,不会 消费 信号量。
§绑定到信号选择器
信号量是 同步对象 ,可以通过方法 Sem::bind()
将信号量绑定到信号选择器 Sel<M>
上,通过 Sel<M>
,单一线程可以同时等待多个不同的 同步对象 。
信号量采用 独占 的方式进行绑定。
§示例
Structs§
- 信号量对象结构体
- 信号量的选择子
Enums§
- 信号量的错误码
Constants§
- XWOS信号量对象占用的内存大小