事件集
1 事件集概念
事件是一种实现线程间通信的机制,主要用于实现线程间的同步,但事件通信只能是事件类型的通信,无数据传输。一个事件发生即是一个同步,事件集可以实现一对多(一个线程等待多个事件触发)、多对多(多个线程等待多个事件触发)的同步。
其中,一个线程与多个事件的关系可以设为:
特定事件触发唤醒线程
其中任意一个事件触发唤醒线程
几个事件都触发后才唤醒线程
1.1 事件集与信号量的区别
对于事件集,接收线程可以等待多个事件同步,即多个事件对应一个或多个线程;而信号量只能识别处理单一释放动作,而不能同时等待多种类型的释放。
事件的发送(相当于信号量的释放)在事件未清除前,是不可累加的,而信号量的释放动作是可以累加的(因此可以用于资源计数)。
1.2 事件集工作机制
事件的集合可以用一个 32 位无符号整型变量来表示,变量的每一位代表一个事件,线程通过 逻辑与或逻辑或将一个或多个事件关联起来,形成事件组合。
逻辑或:也称为独立型同步,指线程与任何事件之一发生同步;
逻辑与:也称为关联型同步,指的是线程与若干事件都发生同步。
逻辑或和逻辑与只能二选一,不可一起使用
示例
/*
* @Descripttion: 事件集初始化源文件
* @version: V1.00
* @Author: fanyuzhao
* @Date: 2024-08-20 12:03:45
* @LastEditTime: 2024-08-20 11:07:39
*/
// RT_EVENT_FLAG_OR 线程选择使用逻辑或来接收事件。
// RT_EVENT_FLAG_AND 线程选择使用逻辑与来接收事件。
// RT_EVENT_FLAG_CLEAR 当线程收到相应的事件时,函数决定是否清除事件标志
#include "EventInit.h"
//线程同步事件集
struct rt_event ThreadSync;
rt_uint32_t EventFlagValue = 0;
#ifdef MIDDLE_WARE_EVENT_INIT
/**
* @name: EventCtrlInit
* @msg: 事件集初始化,用于各个线程的同步
* @param 无
* @return the operation status, RT_EOK on successful
* @note: 事件集标志设置为优先级,即优先级高的线程最先运行
*/
rt_err_t EventCtrlInit(void)
{
rt_err_t result;
result = rt_event_init(&ThreadSync,"ThreadSync",RT_IPC_FLAG_PRIO);
if (result != RT_EOK)
{
rt_kprintf("init %s event failed.\n", "ThreadSync");
return RT_ERROR;
}
return result;
}
/**
* @name: SendEvent
* @msg: 发送一个事件
* @param {rt_uint32_t} EventFlag
* @return the operation status, RT_EOK on successful
* @note: 本质为SendEvent
*/
rt_err_t SendEvent(rt_uint32_t EventFlag)
{
rt_err_t result;
result = rt_event_send(&ThreadSync,EventFlag);
return result;
}
/**
* @name: WaitForThreadSync
* @msg: 等待各线程涉及的资源(硬件/软件)初始化完成,达到线程同步的目的
* @param 无
* @return the operation status, RT_EOK on successful
* @note: 本质为rt_event_recv
*/
rt_err_t WaitForThreadSync(void)
{
rt_err_t result;
result = rt_event_recv(&ThreadSync,(EVENT_FLAG_RecvDataFromUart\
|EVENT_FLAG_ParseDataFromUart|EVENT_FLAG_Main),
RT_EVENT_FLAG_AND,RT_WAITING_FOREVER,&EventFlagValue);
return result;
}
#endif
```c
/*
* @Descripttion: 事件集初始化头文件
*/
#ifndef EVENT_INIT_H
#define EVENT_INIT_H
#include <rtthread.h>
//线程同步事件集相关
#define EVENT_FLAG_RecvDataFromUart (1 << 0)
#define EVENT_FLAG_ParseDataFromUart (1 << 1)
#define EVENT_FLAG_Main (1 << 2)
extern rt_err_t EventCtrlInit(void);
extern rt_err_t SendEvent(rt_uint32_t EventFlag);
extern rt_err_t WaitForThreadSync(void);
#endif