任务的同步与通信_读书笔记_6

来源:互联网 发布:苹果5s如何优化 编辑:程序博客网 时间:2024/06/06 00:39

信号量、信号量的操作(创建信号量、请求信号量、发送信号量、删除信号量、查询信号量的状态)


4.2信号量及其操作

4.2.1信号量

(1)当事件控制块成员OSEventType的值被设置为OS_EVENT_TYPE_SEM时,这个事件控制块描述的就是一个信号量。

(2)信号量是由信号量计数器和任务等待表两部分组成。

(3)每当有任务申请信号量时,

如果信号量计数器OS_EventCnt() > 0,OSEventCnt – 1,任务继续运行;

OS_EventCnt() == 0, OSEventCnt = 0,任务列入等待表;

如果正在使用信号量的任务释放了该信号量,就会在任务等待表中找出优先级别最高的等待任务,并在使它就绪后调用调度器引发一次调度;

如果任务等待表汇总没有等待任务,信号量+ 1;

 

4.2.2信号量的操作

1.创建信号量

在使用信号量之前,应用程序必须调用函数OSSemCreate()来创建一个信号量。

函数原型:

OS_EVENT *OSSemCreate(

                      INT16U cot            //信号量计数器初值

);

返回值为已创建的信号量的指针。

2.请求信号量

(1)任务通过调用函数OSSemPend()请求信号量,函数原型:

void OSSemPend(

               OS_EVNET *pevent,    //信号量的指针

               INT16U timeout,      //等待时限

               INT8U *err           //错误信息

);

参数pevent是被请求信号量的指针。

timeout:任务等待时间限制,超过该时间可以结束等待状态而进入就绪状态。

        timeout = 0时,等待时间无限长。

err:调用成功后值为OS_NO_ERR,失败则会根据出现的具体错误产生不同的值。

(2)访问共享资源时,先请求管理该资源的信号量,根据信号量是否有效决定该任务是否可以继续运行。

(3)如果希望在信号量无效时准许任务不进入等待状态而继续运行,则不用函数OSSemPend(),而是调用函数OSSemAccept()来请求信号量。

3.发送信号量

(1)释放信号量也叫发送信号量;

(2)发送信号量必须调用函数OSSemPost():

该函数对信号量计数器操作之前,先检查是否还有等待该信号量的任务;

没有—>OSEvemtCnt + 1;

有  -->调度器OS_Sched()运行等待任务中优先级别最高的任务。

4.删除信号量

(1)OSSemDel()

原型:

OS_EVENT *OSSemDel(

                   OS_EVENT *pevent,     //信号量的指针

                   INT8U opt,            //删除条件选择

                   INT8U *err            //错误信息

);

opt:指明信号量的删除条件,该参数有两个参数值可以选择:

OS_DEL_NO_PEND,当等待任务表中已没有等待任务时才删除信号量

OS_DEL_ALLWAYS,等待任务中无论是否有等待任务,都立即删除信号量。

(2)注意:只能在任务中删除信号量,不能在中断服务程序中删除。

5.查询信号量的状态

(1)OSSemQuery(),随时查询信号量的当前状态;

(2)原型:

INT8U OSSemQuery

{

   OS_EVENT_ *pevent,      //信号量指针

   OS_SEM_DATA *pdata      //存储信号量装入结构

};

0 0