Expand description
§XWOS RUST:消息队列
XWOS RUST的消息队列是仿照 std::sync::mpsc  编写的。可以有多个发送者,但只能有一个接收者。
XWOS RUST的消息队列是一个先进先进(FIFO)队列。
消息队列在创建时,需要指定一个类型 T ,发送和接收的数据只能是类型 T 的数据。
发送时,消息队列会通过 Box 将类型 T 的数据存入堆内存中。然后将 Box<T> 的裸指针发送到队列。
可以发送到尾端(入队 XwmqTx::eq() ),也可将消息发送到队列的首端(插队 XwmqTx::jq() )。
接收时,会从队列中取出 T 的裸指针,然后恢复成 Box<T> 后返回,由于 Box 能自动释放内存,因此用户不需要关心内存释放的问题。
接收消息可以从首端接收,也可以从尾端接收。
§创建
XWOS RUST的消息队列可使用 Xwmq::new() 创建。创建时需要指定两个类型参数:发送消息槽的个数以及消息数据的类型。
- 可以创建具有静态生命周期 static约束的全局变量:
use xwrust::xwmd::xwmq::*;
static MQ: Xwmq<16, String> = Xwmq::new(); // 16个消息槽,数据类型为String- 也可以使用 alloc::sync::Arc在heap中创建:
extern crate alloc;
use alloc::sync::Arc;
use xwrust::xwmd::xwmq::*;
pub fn xwrust_example_xwmq() {
    let mq: Arc<Xwmq<16, String>> = Arc::new(Xwmq::new()); // 16个消息槽,数据类型为 `String`
}§初始化
无论以何种方式创建的消息队列,都必须在使用前调用 Xwmq::init() 进行初始化,
初始化后会返回消息队列的发送者 XwmqTx 以及接收者 XwmqRx 。
pub fn xwrust_example_xwmq() {
    let (tx, rx) = MQ.init();
}§发送
Xwmq 的发送者 XwmqTx 具有 Send 约束,可在线程之间转移所有权,但不能在线程之间共享( !Sync )。
发送者 XwmqTx 可被 XwmqTx::clone() 为多个发送者,由不同线程持有,向接收者 XwmqRx 发送消息。
§入队
入队 方式是将消息发送到队列的 尾端 , 入队 时,会通过 Box 将数据放入heap中,然后进行发送。
§等待入队
方法 XwmqTx::eq() 只可在 线程 上下文中使用:
- 当消息队列中没有可用的消息槽可用时,发送线程会阻塞等待。
- 当消息队列中有可用的消息槽时,发送线程被唤醒,并取走一个消息槽,并发送数据。
- 当线程阻塞等待被中断时,返回 XwmqError::Interrupt。
§超时等待入队
方法 XwmqTx::eq_to() 只可在 线程 上下文中使用:
- 当消息队列中没有可用的消息槽可用时,发送线程会阻塞等待,等待时会指定一个唤醒时间点。
- 当消息队列中有可用的消息槽时,发送线程被唤醒,并取走一个消息槽,并发送数据。
- 当线程阻塞等待被中断时,返回 XwmqError::Interrupt。
- 当到达指定的唤醒时间点,线程被唤醒,并返回 XwmqError::Timedout。
§等待入队,且等待不可不中断
方法 XwmqTx::eq_unintr() 只可在 线程 上下文中使用:
- 当消息队列中没有可用的消息槽可用时,发送线程会阻塞等待。
- 发送线程的阻塞等待不可被中断。
- 当消息队列中有可用的消息槽时,发送线程被唤醒,并取走一个消息槽,并发送数据。
§尝试等待入队
方法 XwmqTx::tryeq() 方法可在 任意 上下文中使用,不会阻塞,只会检测信号量的值:
- 当消息队列中没有可用的消息槽可用时,立即返回 XwmqError::NoSlot。
- 当消息队列中有可用的消息槽时,发送线程会取走一个消息槽,并发送数据。
§插队
插队 方式是将消息发送到队列的 首端 , 插队 时,会通过 Box 将数据放入heap中,然后进行发送。
§等待插队
方法 XwmqTx::jq() 只可在 线程 上下文中使用:
- 当消息队列中没有可用的消息槽可用时,发送线程会阻塞等待。
- 当消息队列中有可用的消息槽时,发送线程被唤醒,并取走一个消息槽,并发送数据。
- 当线程阻塞等待被中断时,返回 XwmqError::Interrupt。
§超时等待插队
方法 XwmqTx::jq_to() 只可在 线程 上下文中使用:
- 当消息队列中没有可用的消息槽可用时,发送线程会阻塞等待,等待时会指定一个唤醒时间点。
- 当消息队列中有可用的消息槽时,发送线程被唤醒,并取走一个消息槽,并发送数据。
- 当线程阻塞等待被中断时,返回 XwmqError::Interrupt。
- 当到达指定的唤醒时间点,线程被唤醒,并返回 XwmqError::Timedout。
方法 XwmqTx::jq_unintr() 只可在 线程 上下文中使用:
- 当消息队列中没有可用的消息槽可用时,发送线程会阻塞等待。
- 发送线程的阻塞等待不可被中断。
- 当消息队列中有可用的消息槽时,发送线程被唤醒,并取走一个消息槽,并发送数据。
§尝试等待插队
方法 XwmqTx::tryjq() 方法可在 任意 上下文中使用,不会阻塞,只会检测信号量的值:
- 当消息队列中没有可用的消息槽可用时,立即返回 XwmqError::NoSlot。
- 当消息队列中有可用的消息槽时,发送线程会取走一个消息槽,并发送数据。
§接收
Xwmq 的接收者 XwmqRx 具有 Send 约束,可在线程之间转移所有权,但不能在线程之间共享( !Sync )。
接收者 XwmqRx 不可被 ”克隆“,因为接收者只能有一个。
接收消息后,会释放消息槽。若有发送线程正在等待消息槽,将唤醒发送线程。
§首端离队
从消息队列的 首端 取出消息,称为 首端离队 。
接收成功,消息 离队 时,会通过 Box::from_raw() 将数据重新放入 Box 中,然后通过 Ok() 返回。
当 Box 被 drop() 时,会自动释放heap内存。
§等待离队
方法 XwmqRx::dq() 只可在 线程 上下文中使用:
- 当消息队列中没有消息时,接收线程会阻塞等待。
- 当消息队列中有可用的消息时,接收线程被唤醒,并取走一个消息,并释放消息槽。
- 当线程阻塞等待被中断时,通过 Err()返回XwmqError::Interrupt。
§超时等待离队
方法 XwmqRx::dq_to() 只可在 线程 上下文中使用:
- 当消息队列中没有消息时,接收线程会阻塞等待,等待时会指定一个唤醒时间点。
- 当消息队列中有可用的消息时,接收线程被唤醒,并取走一个消息,释放消息槽。
- 当线程阻塞等待被中断时,通过 Err()返回XwmqError::Interrupt。
- 当到达指定的唤醒时间点,线程被唤醒,并通过 Err()返回XwmqError::Timedout。
方法 XwmqRx::dq_unintr() 只可在 线程 上下文中使用:
- 当消息队列中没有消息时,接收线程会阻塞等待。
- 接收线程的阻塞等待不可被中断。
- 当消息队列中有可用的消息时,接收线程被唤醒,并取走一个消息,并释放消息槽。
§尝试等待离队
方法 XwmqRx::trydq() 方法可在 任意 上下文中使用,不会阻塞,只会检测信号量的值:
- 当消息队列中没有消息时,立即通过 Err()返回XwmqError::NoMsg。
- 当消息队列中有可用的消息时,接收线程会取走一个消息,并释放消息槽。
§尾端离队
从消息队列的 尾端 取出消息,称为 尾端离队 。
接收成功,消息 离队 时,会通过 Box::from_raw() 将数据重新放入 Box 中,
然后通过 Ok() 返回。
当 Box 被 drop() 时,会自动释放heap内存。
§等待反向离队
方法 XwmqRx::rq() 只可在 线程 上下文中使用:
- 当消息队列中没有消息时,接收线程会阻塞等待。
- 当消息队列中有可用的消息时,接收线程被唤醒,并取走一个消息,并释放消息槽。
- 当线程阻塞等待被中断时,通过 Err()返回XwmqError::Interrupt。
§超时等待反向离队
方法 XwmqRx::rq_to() 只可在 线程 上下文中使用:
- 当消息队列中没有消息时,接收线程会阻塞等待,等待时会指定一个唤醒时间点。
- 当消息队列中有可用的消息时,接收线程被唤醒,并取走一个消息,释放消息槽。
- 当线程阻塞等待被中断时,通过 Err()返回XwmqError::Interrupt。
- 当到达指定的唤醒时间点,线程被唤醒,并通过 Err()返回XwmqError::Timedout。
方法 XwmqRx::rq_unintr() 只可在 线程 上下文中使用:
- 当消息队列中没有消息时,接收线程会阻塞等待。
- 接收线程的阻塞等待不可被中断。
- 当消息队列中有可用的消息时,接收线程被唤醒,并取走一个消息,并释放消息槽。
§尝试等待反向离队
方法 XwmqRx::tryrq() 方法可在 任意 上下文中使用,不会阻塞,只会检测信号量的值:
- 当消息队列中没有消息时,立即通过 Err()返回XwmqError::NoMsg。
- 当消息队列中有可用的消息时,接收线程会取走一个消息,并释放消息槽。
§示例
XWOS/xwam/xwrust-example/xwrust_example_xwmq
§对比 std::sync::mpsc
- XWOS RUST:
#![no_std]
extern crate alloc;
use xwrust::xwos::thd;
use xwrust::xwmd::xwmq::*;
static MQ: Xwmq<16, u32> = Xwmq::new();
pub fn xwrust_example_xwmq() {
    println!("XWOS RUST Example: XWMQ");
    let (tx, rx) = MQ.init();
    let _ = thd::Builder::new()
                .spawn(move |_| { // 子线程闭包
                    tx.eq(53);
                    "OK"
                });
    let rc = rx.dq();
    match rc {
        Ok(d) => { // d为接收到的数据,并被放在智能指针Box中
        },
        Err(e) => {
        },
    };
}use std::thread;
use std::sync::mpsc::sync_channel;
let (tx, rx) = sync_channel::<i32>(0);
thread::spawn(move|| {
    tx.send(53).unwrap();
});
rx.recv().unwrap();§构建全局变量的方式
- std::sync::mpsc没有编译期构造函数,因此只能借助 宏- lazy_static!创建全局变量;
- xwrust::xwmd::xwmq则可以直接在函数外部定义。
§通道类型
- std::sync::mpsc还有异步的通道- std::sync::mpsc::channel();
- xwrust::xwmd::xwmq通过- Xwmq::init()返回的是类似于- std::sync::mpsc::sync_channel()的通道,- xwrust::xwmd::xwmq没有异步的通道 。
§接收消息返回方式不同
- std::sync::mpsc接收到消息后,直接返回类型为 T 的消息;
- xwrust::xwmd::xwmq则返回- Box<T>。
Structs§
- 消息队列对象结构体
Enums§
- 消息队列的错误码
Constants§
- 消息队列对象占用的内存大小
- 消息占用的内存大小