请选择 进入手机版 | 继续访问电脑版
快捷导航

注册后可查看大图哦

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
本帖最后由 袁绪蝶 于 2017-12-21 21:05 编辑

一、信号量
1 信号量定义
信号量定义:
——信号量是一种约定机制,作用:
控制共享资源的使用权(满足互斥条件);
标志某个事件的发生,使两个任务的行为同步。

信号量种类:

二值信号量:只允许信号量取0或1值,其同时只能被一个线程获取;
计数式信号量:值域不受限制,
在系统运行过程中,计数信号量的值动态反映了当前闲置共享资源实体的个数。
μC/OS-Ⅱ 中的信号量由2部分组成(是否说明μC/OS-Ⅱ 中的信号量只有计数式信号量???)
1)16位的无符号整形信号量的计数值(0~65535)
2)等待该信号量的任务组成的等待任务表。

2 信号量的使用

对信号量的操作:
——建立(CREATE)
即初始化(INITIALIZE):初始化时需要给信号量赋初值,等待信号量的任务列表应置为空。
——挂起(PEND)
即等信号(WAIT):想得到信号量的任务执行WAIT操作,如果该信号量有效(信号量值>0),信号量值-1,任务得以运行。如果信号量值==0,任务进入等待信号量列表。
——发信号(POST)
即给信号(SIGNAL):任务释放信号量。如果没有任务在等待信号量,信号量自增;如果有任务在等待信号,那会有一个任务进入就绪态。
信号量使用方法:
——控制共享资源使用权(满足互斥条件)
—如果信号量是用于对共享资源的访问,那么该信号量的初始值应设为1(例如,把它当作二值信号量使用)。
—如果该信号量是用来表示允许任务访问n个相同的资源,那么该初始值显然应该是n,并把该信号量作为一个可计数的信号量使用。
——标志某个事件的发生
—如果信号量是用来表示一个或者多个事件的发生,那么该信号量的初始值应设为0。

3 二值信号量控制共享资源

使用信号量前对信号量初始化,作为互斥条件,信号量初始化为1;
需要使用共享数据的任务调用OSSemPend();
处理完数据之后,释放信号量OSSemPost()。
信号量的隐藏
某些情况,为了使用方便,将信号量隐藏,用户不知道自己实际上在申请信号量;
优点:任务发送数据的时候,不知道自己在等待信号量,以为只是发送数据没有返回而已。
(但是并没有节约时间或者什么啊,这样算什么优点?)
4 计数式信号量控制共享资源
计数式信号量管理缓冲区阵列(buffer pool);
缓冲区阵列中有10个缓冲区;
通过申请缓冲区函数BufReq()申请资源;
使用完后调用BufRel()释放资源。

5 信号量实现同步

单向同步 双向同步(两个任务要用两个信号量来同步他们的行为)
一个任务做I/O操作,等待信号回应;
任务1运行到某处发信号给任务2,然后等待信号返回;
I/O操作完成后,中断服务程序(或者另一个任务)发出信号;
同样任务2运行到某处发信号给任务1,然后等待信号返回。
该任务的得到此信号,继续往下执行。
这样两个任务实现了双向同步;

注意:任务与中断之间不可以使用双向同步。
**************************************************************
二、信号量通用操作
1 建立一个信号量

OSSemCreate()程序流程
——从空闲任务控制块链表中得到一个事件控制块;
——若得到事件控制块,对事件控制块初始化:事件类型、信号量初值、等待任务列表;初始化完毕,返回事件控制块指针,OSSemPend(), OSSemPost(), OSSemAccept()和OSSemQuery()都是通过该指针完成的;
——若未得到事件控制块,返回NULL。

信号量赋初值cnt:
——建立信号量,并对信号量初始计数值。
如果信号量是用来表示一 个或者多个事件的发生,那么该信号量的初始值应设为0;
如果信号量是用于对共享资源的访问,那么该信号量的初始值应设为1(例如,把它当作二值信号量使用);
如果该信号量是用 来表示允许任务访问n个相同的资源,那么该初始值显然应该是n,并把该信号量作为一个可计数的信号量使用。

2 等待一个信号量

OSSemPend()
等待一个信号量,实际上是申请资源:
如果当前有资源,此函数可以顺利返回;
如果当前没有资源,调用此函数后,进程就睡眠在这个函数里,直到获得资源,才能从此函数返回(相当于主动让出CPU控制权,再等待CPU控制权)。
OSSemPend()最长等待时间:
OSSemPend()允许用户定义一个最长等待时间作为它的参数,这样可以避免该任务无休止地等待下去。
OSSemPend()函数通过将任务控制块中的状态标志.OSTCBStat置1,把任务置于睡眠状态。等待时间也同时置入任务控制块中,该值在OSTimeTick()函数中被逐次递减。


3 发出一个信号量

OSSemPost()
释放一个信号量,实际上是释放资源;
释放信号量会唤醒等待此信号量的最高优先级任务,执行任务调度;
当就绪表中最高优先级任务比当前任务高时,当前任务被剥夺CPU控制权(表现为死在Sched()函数里,直到再次获得CPU控制权,当前任务没有离开就绪表,但是CPU控制权被抢占)。


4 无等待地请求一个信号量

OSSemAccept()
——当一个任务请求一个信号量时,如果该信号量暂时无效,也可以让该任务简单地返回,而不是进入睡眠等待状态。
——调用函数需要对该返回值进行检查。
如果该值是0,说明该信号量无效。
如果该值大于0,说明该信号量有效,将信号量的原有计数值返回给调用函数,同时该值也暗示着该信号量当前可用的资源数。这些可用资源中,已经被该调用函数自身占用了一个。
——中断服务子程序要请求信号量时,只能用OSSemAccept()而不能用OSSemPend(),因为中断服务子程序是不允许等待的。


5 查询一个信号量的当前状态

OSSemQuery()
——来查询一个信号量的当前状态。
——两个参数:
one:指向信号量对应事件控制块的指针pevent。该指针是在生产信号量时,由OSSemCreate()函数返回的;
two:指向用于记录信号量信息的数据结构OS_SEM_DATA(见uCOS_II.H)的指针pdata。

*************************************************************
三、互斥信号量
1 互斥信号量

互斥信号量Mutex
任务可以用互斥型信号量实现对共享资源的独占式处理。互斥型信号量也称作mutex。
Mutex是二值信号量(只允许信号量取0或1值)。
三个元素组成:
1个标志,指示mutex是否可以使用(0或1)。
1个优先级,准备一旦高优先级的任务需要这个mutex,赋给占有mutex的任务。
1个等待该mutex的任务列表。

2 OSMutexCreate()

建立一个互斥型信号量
3 OSMutexPend()

等待一个互斥型信号量

4 OSMutexPost()
释放一个互斥型信号量

5 OSMutexAccept()
无等待地获取一个互斥型信号量(任务不挂起)

6 OSMutexQuery()
获取一个互斥型信号量的当前状态



Connecting & Messaging from Any.

共 0 个关于本帖的回复 最后回复于 2017-12-21 20:25

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

推荐板块

精彩推荐

热门排行

明星用户

手机版|小黑屋|AnyMSG ( ©AnyMSG 2009 - 2017 · ICP备16009991号 )

GMT+8, 2019-2-16 18:59