Expand description
§XWOS RUST:信号选择器
信号选择器使用位图 Bmp
来管理一组 同步对象 。使得单一线程可以同时等待多个 同步对象 。
每个 同步对象 在信号选择器位图中都绑定一个特定的 位 ,
当这些 同步对象 发送 选择信号 时,信号选择器位图中特定的 位 被置 1 ,同时唤醒正在等待信号选择器的线程。 线程唤醒后可以通过检测哪些 位 被置 1 来判断哪些 同步对象 发送了 选择信号 。
§同步对象的绑定与解绑
XWOS RUST的所有 同步对象 都有一个相似的用于绑定的方法:
绑定后会返回各个 同步对象 的 选择子 :
选择子 被 drop()
时,会自动解绑。
同步对象 绑定操作又分为 独占绑定 与 非独占绑定 :
- 独占绑定:是指 同步对象 一旦绑定了信号选择器位图中的某一位后,其他 同步对象 不可再绑定此位,发送的 选择信号 也被称为 独占 方式的 选择信号 ;
- 非独占绑定:是指 同步对象 一旦绑定了信号选择器位图中的某一位后,其他 同步对象 还可继续再绑定此位,发送的 选择信号 也被称为 非独占 方式的 选择信号 。
同步对象 采用的绑定方式:
- 信号量:独占绑定
- 条件量:非独占绑定
- 事件标志:非独占绑定
- 线程栅栏:非独占绑定
- 信号选择器:非独占绑定
§选择信号
§选择信号的设置
选择信号 的设置,对于不同的 同步对象 有不同解释:
- 信号量
- 计数器的值大于 0 时就会被设置。
- 条件量
- 广播操作
Cond::broadcast
- 广播操作
- 事件标志
- 线程栅栏
- 所有线程抵达栅栏,并同时被唤醒;
- 信号选择器
- 信号选择器本身也是 同步对象 ,也可绑定在另一个信号选择器上。当源信号选择器收到了 选择信号 ,会将其传递到绑定的另一个目的信号选择器上。
§选择信号的清除
§独占 方式的 选择信号
- 信号量:当信号量中的计数器的值小于等于 0 时, 选择信号 才会被清除。
§非独占 方式的 选择信号
非独占 方式绑定的 同步对象 向信号选择器发送 选择信号 后,其位图中的位置会被置 1 。 同时会唤醒所有等待的线程,此时线程们会竞争进入信号选择器的临界区。
最先进入的线程会读取信号选择器的 选择信号 位图,并与调用函数时传递的 掩码 进行比较,判断是否有 掩码 中的 选择信号 :
- 如果有,会清除信号选择器位图中 所有 的 非独占 方式的 选择信号 ,包括 掩码 中没有设置的 选择信号 。 因此后续线程将无法再检测到任何 非独占 方式的 选择信号 ,会重新阻塞等待。 XWOS不推荐在信号选择器上,多于1个线程等待。
- 如果没有,线程会重新阻塞等待。然后下一个线程进入临界区检测。
§创建
XWOS RUST的信号量可使用 Sel::new()
创建。
创建时需要指明泛型中的常量 N
,表示信号选择器中有个多少个位置可以绑定。
- 可以创建具有静态生命周期
static
约束的全局变量:
use xwrust::xwos::sync::sel::*;
static GLOBAL_SEL: Sel<8> = Sel::new();
- 也可以使用
alloc::sync::Arc
在heap中创建:
extern crate alloc;
use alloc::sync::Arc;
use xwrust::xwos::sync::sel::*;
pub fn xwrust_example_sel() {
let sel = Arc::new(Sel::<8>::new());
}
§初始化
无论以何种方式创建的信号选择器,都必须在使用前调用 Sel::init()
进行初始化:
pub fn xwrust_example_sel() {
GLOBAL_SEL.init();
sel.init();
}
§等待信号选择器中的 选择信号
Sel::select()
可用于等待信号选择器中的 选择信号 。
- 当没有同步对象向信号选择器发送 选择信号 时,线程会阻塞等待。
- 当 任意 同步对象向信号选择器发送 选择信号 时,线程被唤醒,然后返回
Bmp<N>
。 - 当线程阻塞等待被中断时,返回
SelError::Interrupt
。
§限时等待信号选择器中的 选择信号
Sel::select_to()
可用于限时等待信号选择器中的 选择信号 。
- 当没有同步对象向信号选择器发送 选择信号 时,线程会阻塞等待,等待时会指定一个唤醒时间点。
- 当 任意 同步对象向信号选择器发送 选择信号 时,线程被唤醒,然后返回
Bmp<N>
。 - 当线程阻塞等待被中断时,返回
SelError::Interrupt
。 - 当到达指定的唤醒时间点,线程被唤醒,并返回
SelError::Timedout
。
Sel::tryselect()
检测信号选择器中是否有 选择信号 。
- 当检测到 任意 同步对象向信号选择器发送 选择信号 时,立即返回
Bmp<N>
。 - 当没有同步对象向信号选择器发送 选择信号 时,立即返回
SelError::NoSignal
。
§获取信号选择器中同步对象槽的数量
可以通过方法 Sel::get_num()
获取信号选择器中位置的数量,这个值是在创建信号选择器时通过泛型常量 N
指定的。
§绑定到其他信号选择器
信号选择器也是 同步对象, 可以通过方法 Sel::bind()
将信号选择器绑定到另一个信号选择器上,由此可将 选择信号 进行传递。
信号选择器采用 非独占 的方式进行绑定。
§示例
Structs§
- 信号选择器对象结构体
- 信号选择器的选择子
Enums§
- 信号选择器的错误码
Constants§
- XWOS信号选择器对象占用的内存大小