RT_Thread_事件集
1、事件集
用一个 32 位无符号整型变量来表示,每一位代表一个事件,线程通过 “逻辑与” 或“逻辑或”将一个或多个事件关联起来,形成事件组合。
- 事件的 “逻辑或” 也称为是独立型同步,指的是线程与任何事件之一发生同步;
- 事件的 “逻辑与” 也称为是关联型同步,指的是线程与若干事件都发生同步。
2、事件集API
2.1、创建和删除
- 静态事件集
rt_err_t rt_event_init(rt_event_t event, const char* name, rt_uint8_t flag);
参数 | 描述 |
---|---|
event | 事件集对象的句柄 |
name | 事件集的名称 |
flag |
事件集的标志,它可以取如下数值: RT_IPC_FLAG_FIFO 或 RT_IPC_FLAG_PRIO, 建议采用 RT_IPC_FLAG_PRIO,即确保线程的实时性。 |
返回 | —— |
RT_EOK | 成功 |
rt_err_t rt_event_detach(rt_event_t event);
参数 | 描述 |
---|---|
event | 事件集对象的句柄 |
返回 | —— |
RT_EOK | 成功 |
- 动态事件集
rt_event_t rt_event_create(const char* name, rt_uint8_t flag);
参数 | 描述 |
---|---|
name | 事件集的名称 |
flag |
事件集的标志,它可以取如下数值: RT_IPC_FLAG_FIFO 或 RT_IPC_FLAG_PRIO, 建议采用 RT_IPC_FLAG_PRIO,即确保线程的实时性。 |
返回 | —— |
RT_NULL | 创建失败 |
事件对象的句柄 | 创建成功 |
rt_err_t rt_event_delete(rt_event_t event);
参数 | 描述 |
---|---|
event | 事件集对象的句柄 |
返回 | —— |
RT_EOK | 成功 |
2.2、发送事件
通过参数 set 指定的事件标志来设定 event 事件集对象的事件标志值,然后遍历等待在 event 事件集对象上的等待线程链表,判断是否有线程的事件激活要求与当前 event 对象事件标志值匹配,如果有,则唤醒该线程。
rt_err_t rt_event_send(rt_event_t event, rt_uint32_t set);
参数 | 描述 |
---|---|
event | 事件集对象的句柄 |
set | 发送的一个或多个事件的标志值 |
返回 | —— |
RT_EOK | 成功 |
2.3、接收事件
根据 set 和 option 来判断它要接收的事件是否发生。
- 如果已经发生,则根据参数 option 上是否设置有 RT_EVENT_FLAG_CLEAR 来决定是否重置事件的相应标志位,然后返回(其中 recved 参数返回接收到的事件);
- 如果没有发生,则把等待的 set 和 option 参数填入线程本身的结构中,然后把线程挂起在此事件上,直到其等待的事件满足条件或等待时间超时。
rt_err_t rt_event_recv(rt_event_t event,rt_uint32_t set,rt_uint8_t option,rt_int32_t timeout,rt_uint32_t* recved);
参数 | 描述 |
---|---|
event | 事件集对象的句柄 |
set | 接收线程感兴趣的事件 |
option |
接收选项:RT_EVENT_FLAG_OR逻辑或;RT_EVENT_FLAG_AND逻辑与; RT_EVENT_FLAG_CLEAR清除事件标志; |
timeout | 指定超时时间 |
recved | 指向接收到的事件 |
返回 | —— |
RT_EOK | 成功 |
-RT_ETIMEOUT | 超时 |
-RT_ERROR | 错误 |
3、例程
#include <rtthread.h>#define THREAD_PRIORITY 9
#define THREAD_TIMESLICE 5#define EVENT_FLAG3 (1 << 3)
#define EVENT_FLAG5 (1 << 5)/* 事件控制块 */
static struct rt_event event;ALIGN(RT_ALIGN_SIZE)
static char thread1_stack[1024];
static struct rt_thread thread1;/* 线程1入口函数 */
static void thread1_recv_event(void *param)
{rt_uint32_t e;/* 第一次接收事件,事件3或事件5任意一个可以触发线程1,接收完后清除事件标志 */if (rt_event_recv(&event, (EVENT_FLAG3 | EVENT_FLAG5),RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,RT_WAITING_FOREVER, &e) == RT_EOK){rt_kprintf("thread1: OR recv event 0x%x\n", e);}rt_kprintf("thread1: delay 1s to prepare the second event\n");rt_thread_mdelay(1000);/* 第二次接收事件,事件3和事件5均发生时才可以触发线程1,接收完后清除事件标志 */if (rt_event_recv(&event, (EVENT_FLAG3 | EVENT_FLAG5),RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR,RT_WAITING_FOREVER, &e) == RT_EOK){rt_kprintf("thread1: AND recv event 0x%x\n", e);}rt_kprintf("thread1 leave.\n");
}ALIGN(RT_ALIGN_SIZE)
static char thread2_stack[1024];
static struct rt_thread thread2;/* 线程2入口 */
static void thread2_send_event(void *param)
{rt_kprintf("thread2: send event3\n");rt_event_send(&event, EVENT_FLAG3);rt_thread_mdelay(200);rt_kprintf("thread2: send event5\n");rt_event_send(&event, EVENT_FLAG5);rt_thread_mdelay(200);rt_kprintf("thread2: send event3\n");rt_event_send(&event, EVENT_FLAG3);rt_kprintf("thread2 leave.\n");
}int event_sample(void)
{rt_err_t result;/* 初始化事件对象 */result = rt_event_init(&event, "event", RT_IPC_FLAG_FIFO);if (result != RT_EOK){rt_kprintf("init event failed.\n");return -1;}rt_thread_init(&thread1,"thread1",thread1_recv_event,RT_NULL,&thread1_stack[0],sizeof(thread1_stack),THREAD_PRIORITY - 1, THREAD_TIMESLICE);rt_thread_startup(&thread1);rt_thread_init(&thread2,"thread2",thread2_send_event,RT_NULL,&thread2_stack[0],sizeof(thread2_stack),THREAD_PRIORITY, THREAD_TIMESLICE);rt_thread_startup(&thread2);return 0;
}/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(event_sample, event sample);
msh >event_sample
thread2: send event3
thread1: OR recv event 0x8
thread1: delay 1s to prepare the second event
thread2: send event5
thread2: send event3
thread2 leave.
thread1: AND recv event 0x28
thread1 leave.
RT_Thread_事件集相关推荐
- 任务间同步 | 信号量、互斥量和事件集
本文分享自中移OneOS公众号<任务间同步>. 多个任务操作同一块代码区域,这块代码就称为临界区,如果任何时刻最多只允许一个任务去使用临界区,那么多个任务就需要互斥的访问.当一个任务占用此 ...
- Javascript事件集
一般事件 onclick 鼠标点击时触发此事件 ondblclick 鼠标双击时触发此事件 onmousedown 按下鼠标时触发此事件 onmouseup 按下鼠标后松开鼠标触发此事件 onmou ...
- 使用MPICH构建一个四节点的集群系统
http://selboo.com.cn/post/202/ 1.什么是服务器集群 随着Internet的爆炸性增长,Internet与人的生活越来越息息相关,通过Internet上进行交易也就越来越 ...
- pygame的基础知识详解(主窗口创建、图像绘制、时钟对象和事件响应等知识点),请惠存
各位好,很久没更新博客了,最近较为深入研究pygame库,有些心得体会,想分享给各位,准备做成一个系列知识.欢迎各位查阅. 这篇作为一个基础知识的宣贯,想和各位深入分享一下pygame的基础知识,深入 ...
- Android中高级进阶开发面试题冲刺合集(四)
以下主要针对往期收录的面试题进行一个分类归纳整理,方便大家统一回顾和参考.本篇是第四集~ 强调一下:因篇幅问题:文中只放部分内容,全部面试开发文档需要的可在公众号<Android苦做舟>获 ...
- 显示服务器事件,服务器事件查看
服务器事件查看 内容精选 换一换 本节操作指导用户查看Windows弹性云服务器的登录日志.本节操作以2012操作系统云服务器为例.登录弹性云服务器.选择"开始 > 管理工具 > ...
- 什么是离散事件模拟(DES)
DES(Discrete event simulation) 参考网址: https://www.ncbi.nlm.nih.gov/books/NBK293948/ https://whatis.te ...
- 篇章级的事件抽取——阅读笔记
一.<DCFEE> <DCFEE: A Document-level Chinese Financial Event Extraction System based on Autom ...
- Kubernetes 生产环境安装部署 基于 Kubernetes v1.14.0 之 etcd集群
说明:没有明确注明在某台服务器,都是在k8s-operation 工作服务器完成 K8S node 节点数大于2000 节点 k8s-operation 目录规划,工作目录/apps/work/k8s ...
最新文章
- Revit API导出GBXML
- Django 2.2 LTS 发布,长期支持版来了
- dedeCMS后台入口安全修改
- java集合框架总结(一)
- 使用BaaS更快地构建Xamarin应用程序
- lintcode-87-删除二叉查找树的节点
- 思科路由器端口映射配置实例
- 《C#高效编程》读书笔记11-理解短小方法的优势
- ROS | 机器人操作系统简介
- echarts 生成 迁徙图_Echarts地图的迁徙图
- validation
- leetcode:买卖股票的最佳时机2(python)
- c语言 q15格式,DSP 数据 Q格式
- 基于STM32的EtherCAT从站IO讲解
- leet code: Two Sum
- 最近用到的shell命令
- Android源码-高质量开发库
- OPA 20 - deliberately generate an error
- Chrome浏览器无法翻译
- manjaro-安装idea
热门文章
- MySQL8.0 物理克隆接口_实战 MySQL 8.0.17 Clone Plugin(转)
- 教资计算机报高中害死初中,教师资格证报名入口必须电脑登录吗_中小学教师资格考试网...
- 在深圳,什么行业最有发展前景?
- kingcms标签大全
- 对今天知识的回顾15
- MindSpore论坛十一月活动宣传
- css立体3d效果动画,css3 实现动画,变换基点及3D效果~
- C#: 星座星盘计算算法
- 对华锐风电的一些看法
- flutter重新配置sdk路径_Android studio 切换flutterSDK之后报错及解决办法(推荐)