域名打不开网站,商丘哪里有网站建设,网站开发和ui的区别,如何选择坪山网站建设官方概述
先看官方对事件的描述.
事件#xff08;Event#xff09;是一种任务间通信的机制#xff0c;可用于任务间的同步。
多任务环境下#xff0c;任务之间往往需要同步操作#xff0c;一个等待即是一个同步。事件可以提供一对多、多对多的同步操作。 一对多同步模型…官方概述
先看官方对事件的描述.
事件Event是一种任务间通信的机制可用于任务间的同步。
多任务环境下任务之间往往需要同步操作一个等待即是一个同步。事件可以提供一对多、多对多的同步操作。 一对多同步模型一个任务等待多个事件的触发。可以是任意一个事件发生时唤醒任务处理事件也可以是几个事件都发生后才唤醒任务处理事件。 多对多同步模型多个任务等待多个事件的触发。
鸿蒙提供的事件具有如下特点
任务通过创建事件控制块来触发事件或等待事件。事件间相互独立内部实现为一个32位无符号整型每一位标识一种事件类型。第25位不可用因此最多可支持31种事件类型。事件仅用于任务间的同步不提供数据传输功能。多次向事件控制块写入同一事件类型在被清零前等效于只写入一次。多个任务可以对同一事件进行读写操作。支持事件读写超时机制。
再看事件图 注意图中提到了三个概念 事件控制块 事件 任务 接下来结合代码来理解事件模块的实现.
事件控制块长什么样?
typedef struct tagEvent {UINT32 uwEventID; /** Event mask in the event control block//标识发生的事件类型位事件ID每一位标识一种事件类型indicating the event that has been logically processed. */LOS_DL_LIST stEventList; /** Event control block linked list *///读取事件任务链表
} EVENT_CB_S *PEVENT_CB_S;简单是简单就两个变量如下: uwEventID用于标识该任务发生的事件类型其中每一位表示一种事件类型0表示该事件类型未发生、1表示该事件类型已经发生一共31种事件类型第25位系统保留。
stEventList这又是一个双向链表 双向链表是内核最重要的结构体. LOS_DL_LIST像狗皮膏药一样牢牢的寄生在宿主结构体上stEventList上挂的是所有等待这个事件的任务.
事件控制块事件任务 三者关系
一定要搞明白这三者的关系否则搞不懂事件模块是如何运作的. 任务是事件的生产者通过 LOS_EventWrite向外部广播发生了XX事件并唤醒此前已在事件控制块中登记过的要等待XX事件发生的XX任务. 事件控制块EVENT_CB_S 是记录者只干两件事件: 1.uwEventID按位记录哪些事件发生了它只是记录怎么消费它不管的. 2.stEventList记录哪些任务在等待事件但任务究竟在等待哪些事件它也是不记录的 任务也是消费者通过 LOS_EventRead消费只有任务自己清楚要以什么样的方式消费什么样的事件. 先回顾下任务结构体 LosTaskCB 对事件部分的描述如下: typedef struct {//...去掉不相关的部分VOID *taskEvent; //和任务发生关系的事件控制块UINT32 eventMask; //对哪些事件进行屏蔽UINT32 eventMode; //事件三种模式(LOS_WAITMODE_ANDLOS_WAITMODE_ORLOS_WAITMODE_CLR)} LosTaskCB; taskEvent 指向的就是 EVENT_CB_SeventMask 屏蔽掉 事件控制块 中的哪些事件eventMode 已什么样的方式去消费事件三种读取模式#define LOS_WAITMODE_AND 4U #define LOS_WAITMODE_OR 2U #define LOS_WAITMODE_CLR 1U * 所有事件LOS_WAITMODE_AND逻辑与基于接口传入的事件类型掩码eventMask只有这些事件都已经发生才能读取成功否则该任务将阻塞等待或者返回错误码。* 任一事件LOS_WAITMODE_OR逻辑或基于接口传入的事件类型掩码eventMask只要这些事件中有任一种事件发生就可以读取成功否则该任务将阻塞等待或者返回错误码。* 清除事件LOS_WAITMODE_CLR这是一种附加读取模式需要与所有事件模式或任一事件模式结合使用LOS_WAITMODE_AND | LOS_WAITMODE_CLR或 LOS_WAITMODE_OR | LOS_WAITMODE_CLR。在这种模式下当设置的所有事件模式或任一事件模式读取成功后会自动清除事件控制块中对应的事件类型位。一个事件控制块EVENT_CB_S中的事件可以来自多个任务多个任务也可以同时消费事件控制块中的事件并且这些任务之间可以没有任何关系!
函数列表
事件可应用于多种任务同步场景在某些同步场景下可替代信号量。 其中读懂 OsEventWrite 和 OsEventRead 就明白了事件模块.
事件初始化 - LOS_EventInit
//初始化一个事件控制块
LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventInit(PEVENT_CB_S eventCB)
{UINT32 intSave;intSave LOS_IntLock();//锁中断eventCB-uwEventID 0; //其中每一位表示一种事件类型0表示该事件类型未发生、1表示该事件类型已经发生LOS_ListInit(eventCB-stEventList);//事件链表初始化LOS_IntRestore(intSave);//恢复中断return LOS_OK;
}
代码解读:
事件是共享资源所以操作期间不能产生中断.初始化两个记录者 uwEventID stEventList
事件生产过程 - OsEventWrite LITE_OS_SEC_TEXT VOID OsEventWriteUnsafe(PEVENT_CB_S eventCB UINT32 events BOOL once UINT8 *exitFlag)
{LosTaskCB *resumedTask NULL;LosTaskCB *nextTask NULL;BOOL schedFlag FALSE;eventCB-uwEventID | events;//对应位贴上标签if (!LOS_ListEmpty(eventCB-stEventList)) {//等待事件链表判断处理等待事件的任务for (resumedTask LOS_DL_LIST_ENTRY((eventCB-stEventList)-pstNext LosTaskCB pendList);resumedTask-pendList ! eventCB-stEventList;) {//循环获取任务链表nextTask LOS_DL_LIST_ENTRY(resumedTask-pendList.pstNext LosTaskCB pendList);//获取任务实体if (OsEventResume(resumedTask eventCB events)) {//是否恢复任务schedFlag TRUE;//任务已加至就绪队列申请发生一次调度}if (once TRUE) {//是否只处理一次任务break;//退出循环}resumedTask nextTask;//检查链表中下一个任务}}if ((exitFlag ! NULL) (schedFlag TRUE)) {//是否让外面调度*exitFlag 1;}
}
//写入事件
LITE_OS_SEC_TEXT STATIC UINT32 OsEventWrite(PEVENT_CB_S eventCB UINT32 events BOOL once)
{UINT32 intSave;UINT8 exitFlag 0;SCHEDULER_LOCK(intSave); //禁止调度OsEventWriteUnsafe(eventCB events once exitFlag);//写入事件SCHEDULER_UNLOCK(intSave); //允许调度if (exitFlag 1) { //需要发生调度LOS_MpSchedule(OS_MP_CPU_ALL);//通知所有CPU调度LOS_Schedule();//执行调度}return LOS_OK;
}
代码解读: 给对应位贴上事件标签eventCB-uwEventID | events; 注意uwEventID是按位管理的.每个位代表一个事件是否写入例如 uwEventID 00010010 代表产生了 14 事件 循环从stEventList链表中取出等待这个事件的任务判断是否唤醒任务. OsEventResume
//事件恢复判断是否唤醒任务
LITE_OS_SEC_TEXT STATIC UINT8 OsEventResume(LosTaskCB *resumedTask const PEVENT_CB_S eventCB UINT32 events)
{UINT8 exitFlag 0;//是否唤醒if (((resumedTask-eventMode LOS_WAITMODE_OR) ((resumedTask-eventMask events) ! 0)) ||((resumedTask-eventMode LOS_WAITMODE_AND) ((resumedTask-eventMask eventCB-uwEventID) resumedTask-eventMask))) {//逻辑与 和 逻辑或 的处理exitFlag 1; resumedTask-taskEvent NULL;OsTaskWake(resumedTask);//唤醒任务加入就绪队列}return exitFlag;
}
3.唤醒任务OsTaskWake只是将任务重新加入就绪队列需要立即申请一次调度 LOS_Schedule .
事件消费过程 - OsEventRead LITE_OS_SEC_TEXT STATIC UINT32 OsEventRead(PEVENT_CB_S eventCB UINT32 eventMask UINT32 mode UINT32 timeoutBOOL once)
{UINT32 ret;UINT32 intSave;SCHEDULER_LOCK(intSave);ret OsEventReadImp(eventCB eventMask mode timeout once);//读事件实现函数SCHEDULER_UNLOCK(intSave);return ret;
}//读取指定事件类型的实现函数超时时间为相对时间单位为Tick
LITE_OS_SEC_TEXT STATIC UINT32 OsEventReadImp(PEVENT_CB_S eventCB UINT32 eventMask UINT32 modeUINT32 timeout BOOL once)
{UINT32 ret 0;LosTaskCB *runTask OsCurrTaskGet();runTask-eventMask eventMask;runTask-eventMode mode;runTask-taskEvent eventCB;//事件控制块ret OsTaskWait(eventCB-stEventList timeout TRUE);//任务进入等待状态挂入阻塞链表if (ret LOS_ERRNO_TSK_TIMEOUT) {//如果返回超时runTask-taskEvent NULL;return LOS_ERRNO_EVENT_READ_TIMEOUT;}ret OsEventPoll(eventCB-uwEventID eventMask mode);//检测事件是否符合预期return ret;
}
代码解读:
事件控制块是给任务使用的 任务给出读取一个事件的条件 eventMask 告诉系统屏蔽掉这些事件对屏蔽的事件不感冒. eventMode 已什么样的方式去消费事件是必须都满足给的条件还是只满足一个就响应. 条件给完后自己进入等待状态 OsTaskWait等待多久 timeout决定任务自己说了算. OsEventPoll检测事件是否符合预期啥意思?看下它的代码就知道了 //根据用户传入的事件值、事件掩码及校验模式返回用户传入的事件是否符合预期
LITE_OS_SEC_TEXT UINT32 OsEventPoll(UINT32 *eventID UINT32 eventMask UINT32 mode)
{UINT32 ret 0;//事件是否发生了LOS_ASSERT(OsIntLocked());//断言不允许中断了LOS_ASSERT(LOS_SpinHeld(g_taskSpin));//任务自旋锁if (mode LOS_WAITMODE_OR) {//如果模式是读取掩码中任意事件if ((*eventID eventMask) ! 0) {ret *eventID eventMask; //发生了}} else {//等待全部事件发生if ((eventMask ! 0) (eventMask (*eventID eventMask))) {//必须满足全部事件发生ret *eventID eventMask; //发生了}}if (ret (mode LOS_WAITMODE_CLR)) {//是否清除事件*eventID *eventID ~ret; }return ret;
}
编程实例
本实例实现如下流程。
示例中任务Example_TaskEntry创建一个任务Example_EventExample_Event读事件阻塞Example_TaskEntry向该任务写事件。可以通过示例日志中打印的先后顺序理解事件操作时伴随的任务切换。
在任务Example_TaskEntry创建任务Example_Event其中任务Example_Event优先级高于Example_TaskEntry。在任务Example_Event中读事件0x00000001阻塞发生任务切换执行任务Example_TaskEntry。在任务Example_TaskEntry向任务Example_Event写事件0x00000001发生任务切换执行任务Example_Event。Example_Event得以执行直到任务结束。Example_TaskEntry得以执行直到任务结束。
#include los_event.h
#include los_task.h
#include securec.h/* 任务ID */
UINT32 g_testTaskId;/* 事件控制结构体 */
EVENT_CB_S g_exampleEvent;/* 等待的事件类型 */
#define EVENT_WAIT 0x00000001/* 用例任务入口函数 */
VOID Example_Event(VOID)
{UINT32 ret;UINT32 event;/* 超时等待方式读事件超时时间为100 ticks 若100 ticks后未读取到指定事件读事件超时任务直接唤醒 */printf(Example_Event wait event 0x%x \n EVENT_WAIT);event LOS_EventRead(g_exampleEvent EVENT_WAIT LOS_WAITMODE_AND 100);if (event EVENT_WAIT) {printf(Example_Eventread event :0x%x\n event);} else {printf(Example_Eventread event timeout\n);}
}UINT32 Example_TaskEntry(VOID)
{UINT32 ret;TSK_INIT_PARAM_S task1;/* 事件初始化 */ret LOS_EventInit(g_exampleEvent);if (ret ! LOS_OK) {printf(init event failed .\n);return -1;}/* 创建任务 */(VOID)memset_s(task1 sizeof(TSK_INIT_PARAM_S) 0 sizeof(TSK_INIT_PARAM_S));task1.pfnTaskEntry (TSK_ENTRY_FUNC)Example_Event;task1.pcName EventTsk1;task1.uwStackSize OS_TSK_DEFAULT_STACK_SIZE;task1.usTaskPrio 5;ret LOS_TaskCreate(g_testTaskId task1);if (ret ! LOS_OK) {printf(task create failed .\n);return LOS_NOK;}/* 写g_testTaskId 等待事件 */printf(Example_TaskEntry write event .\n);ret LOS_EventWrite(g_exampleEvent EVENT_WAIT);if (ret ! LOS_OK) {printf(event write failed .\n);return LOS_NOK;}/* 清标志位 */printf(EventMask:%d\n g_exampleEvent.uwEventID);LOS_EventClear(g_exampleEvent ~g_exampleEvent.uwEventID);printf(EventMask:%d\n g_exampleEvent.uwEventID);/* 删除任务 */ret LOS_TaskDelete(g_testTaskId);if (ret ! LOS_OK) {printf(task delete failed .\n);return LOS_NOK;}return LOS_OK;
}
运行结果
Example_Event wait event 0x1
Example_TaskEntry write event .
Example_Eventread event :0x1
EventMask:1
EventMask:0鸿蒙全栈开发全新学习指南
也为了积极培养鸿蒙生态人才让大家都能学习到鸿蒙开发最新的技术针对一些在职人员、0基础小白、应届生/计算机专业、鸿蒙爱好者等人群整理了一套纯血版鸿蒙HarmonyOS Next全栈开发技术的学习路线【包含了大APP实战项目开发】。
本路线共分为四个阶段
第一阶段鸿蒙初中级开发必备技能 第二阶段鸿蒙南北双向高工技能基础gitee.com/MNxiaona/733GH 第三阶段应用开发中高级就业技术 第四阶段全网首发-工业级南向设备开发就业技术https://gitee.com/MNxiaona/733GH 《鸿蒙 (Harmony OS)开发学习手册》共计892页
如何快速入门
1.基本概念 2.构建第一个ArkTS应用 3.…… 开发基础知识:gitee.com/MNxiaona/733GH
1.应用基础知识 2.配置文件 3.应用数据管理 4.应用安全管理 5.应用隐私保护 6.三方应用调用管控机制 7.资源分类与访问 8.学习ArkTS语言 9.……
基于ArkTS 开发
1.Ability开发 2.UI开发 3.公共事件与通知 4.窗口管理 5.媒体 6.安全 7.网络与链接 8.电话服务 9.数据管理 10.后台任务(Background Task)管理 11.设备管理 12.设备使用信息统计 13.DFX 14.国际化开发 15.折叠屏系列 16.……
鸿蒙开发面试真题含参考答案:gitee.com/MNxiaona/733GH 鸿蒙入门教学视频 美团APP实战开发教学gitee.com/MNxiaona/733GH 写在最后
如果你觉得这篇内容对你还蛮有帮助我想邀请你帮我三个小忙点赞转发有你们的 『点赞和评论』才是我创造的动力。关注小编同时可以期待后续文章ing不定期分享原创知识。想要获取更多完整鸿蒙最新学习资源请移步前往小编gitee.com/MNxiaona/733GH