xwrust::xwmd

Module xwmq

source
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
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() 返回。 当 Boxdrop() 时,会自动释放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() 返回。 当 Boxdrop() 时,会自动释放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();

§构建全局变量的方式

§通道类型

§接收消息返回方式不同

Structs§

Enums§

Constants§