rt-thread队列使用

一、介绍

        消息队列跟邮箱差不多,都是一种通信系统,就好比微信,可以让你跟好朋友自如的交换信息。

        消息是一种遵循先进先出的原则,比如装酒的漏斗,先倒进去的先流出来,是一个道理的。哪个线程先放数据,那么其他线程在读的时候,一定是先读到最早放入的那个数据,看下面的示意图就明白了。

二、使用

使用消息队列传输数据时有两种方法:

  • 拷贝:把数据、把变量的值复制进消息队列里
  • 引用:把数据、把变量的地址复制进消息队列里

        只要知道消息队列的句柄,谁都可以读、写该消息队列。线程、ISR 都可读、写消息队列。可以多个线程读写消息队列。线程读写消息队列时,如果读写不成功,可以即刻返回错误,也可以阻塞。阻塞时可以指定超时时间。口语化地说,就是可以定个闹钟:如果能读写了就马上进入就绪态,否则就阻塞直到超时。

比如某个线程读消息队列时:
 如果消息队列中有可用的消息,即刻得到消息并返回
 如果消息队列中没有可用的消息,线程有两种选择:即刻放回一个错误值,或者阻塞一段时间
 如果线程阻塞,它何时被唤醒?
 在指定的时间内,别的线程或者中断服务程序写了队列,会把它唤醒
 否则,指定的时间到达后超时返回错误。既然读写消息队列的线程个数没有限制:
 多个线程都想写队列,但是队列已经满了,这些线程可以进入阻塞状态:它们都在等待队列有空间
 那么:队列有空间时,把那个线程唤醒?

 多个线程都想读队列,但是队列已经空了,这些线程可以进入阻塞状态:它们都在等待队列有数据
 那么:队列有数据时,把那个线程唤醒?
 唤醒谁?有两种方法。创建队列时,可以指定一个参数 flag
 RT_IPC_FLAG_PRIO:表示唤醒优先级最高的等待线程
 RT_IPC_FLAG_FIFO:表示唤醒等待时间最长的等待线程

        代码: 这里也是创建了两个线程,一个发送一个用来接收。我们这里传的是i变量的地址,接收也是获取i的地址,

#include "board.h"               //头文件合集
#include <stdio.h>

struct rt_thread thread1_send_mb; //发送邮箱
struct rt_thread thread2_recv_mb;//接收邮箱
/*队列句柄 */
static rt_mq_t mq = RT_NULL;

rt_uint8_t thread1_stack[512]={0};
rt_uint8_t thread2_stack[512]={0};

char send_arr[]="i love thread";
	
static void thread1_callback(void *parameter)
{
	rt_uint32_t i;
	while(1)
	{ //发送
		rt_mq_send(mq,&i,4);
		i++;
		rt_kprintf("mq succeed!\r\n");
		rt_thread_delay(500);//延时500ms,让thread2可以去运行
	}
}
static void thread2_callback(void *parameter)
{
	rt_uint32_t i=-1;
	while(1)
	{ //接收队列数据
		rt_mq_recv(mq,&i,4,RT_WAITING_FOREVER);	
		rt_kprintf("mq data:%d\r\n",i);
		rt_thread_delay(500);//延时500ms,让thread1可以去运行
	}
}
int main(void)
{	//FIFO模式,先进先出
	mq = rt_mq_create("mq",4,1, RT_IPC_FLAG_FIFO);
	rt_thread_init(&thread1_send_mb,
	"thread1",
	thread1_callback,
	NULL,
	&thread1_stack[0],
	sizeof(thread1_stack),
	7,
	5);
	/*5是时间片,作用是当有相同优先级的线程时,最大执行时间是5 tick
	如果线程毁掉函数执行时间少于5 tick,也会提前返回,切换带到下一个线程
	如果5 tick还没执行完也会切换到下一个线程	*/
	rt_thread_init(&thread2_recv_mb,
	"thread2",
	thread2_callback,
	RT_NULL,
	&thread2_stack[0],
	sizeof(thread2_stack),
	8,
	5);		
	//开启2个线程
	rt_thread_startup(&thread1_send_mb);
	rt_thread_startup(&thread2_recv_mb);
	return 0;
}


结果演示:

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蛋骗鸡~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值