1、嵌入式系统及应用嵌入式系统及应用第六章第六章同步、互斥与通信同步、互斥与通信主要内容主要内容 概述概述 信号量信号量 邮箱和消息队列邮箱和消息队列 事件事件 异步信号异步信号*管道管道*概述概述 多任务系统中任务之间的关系多任务系统中任务之间的关系 相互独立 仅竞争CPU资源 竞争除CPU外的其他资源(互斥)同步 协调彼此运行的步调,保证协同运行的各个任务具有正确的执行次序 通信 彼此间传递数据或信息,以协同完成某项工作 任务能以以下方式与中断处理程序或其任务能以以下方式与中断处理程序或其他任务进行同步或通信:他任务进行同步或通信:单向同步或通信:一个任务与另一个任务或一个ISR同步或通信。双
2、向同步或通信:两个任务相互同步或通信。双向同步不能在任务与ISR之间进行,因为ISR不能等待。概述概述ISR xTask yPOSTPENDTask xTask yPOSTPENDPOSTPENDTask xTask yPOSTPEND 在嵌入式多任务系统中,任务间的在嵌入式多任务系统中,任务间的耦合耦合程度程度是不一样的:是不一样的:耦合程度较高:任务之间需要进行大量的通信,相应的系统开销较大;耦合程度较低:任务之间不存在通信需求,其间的同步关系很弱甚至不需要同步或互斥,系统开销较小。研究任务间耦合程度的高低对于合理地研究任务间耦合程度的高低对于合理地设计应用系统、划分任务有很重要的作设计应
3、用系统、划分任务有很重要的作用。用。概述概述 在单处理器平台上,嵌入式操作系统内在单处理器平台上,嵌入式操作系统内核提供的同步、互斥与通信机制主要包核提供的同步、互斥与通信机制主要包括:括:信号量(semaphore),用于互斥与同步 事件(组)(event group),用于同步 异步信号(asynchronous signal),用于同步 邮箱(mailbox)、消息队列(message queue),用于消息通信 管道(pipe),提供非结构化数据交换和实现同步 概述概述 以下一些机制也可用于同步与通信(在以下一些机制也可用于同步与通信(在单处理器或多处理器系统中):单处理器或多处理器系
4、统中):全局变量 共享内存 Sockets 远程过程调用(Remote Procedure Call)概述概述第一节第一节信号量信号量信号量的种类及用途信号量的种类及用途互斥信号量互斥信号量二值信号量二值信号量计数信号量计数信号量信号量机制的主要数据结构信号量机制的主要数据结构典型的信号量操作典型的信号量操作 信号量用于实现任务与任务之间、任务信号量用于实现任务与任务之间、任务与中断处理程序之间的与中断处理程序之间的同步同步与与互斥互斥。信号量一般分为三种:信号量一般分为三种:信号量的种类及用途信号量的种类及用途用于解决互斥问题。它比较特殊,可能用于解决互斥问题。它比较特殊,可能会引起优先级反
5、转问题。会引起优先级反转问题。用于解决同步问题用于解决同步问题用于解决资源计数问题用于解决资源计数问题将信号量进行种类细分,可以根据其用途,在具体将信号量进行种类细分,可以根据其用途,在具体实现时做专门处理,提高执行效率和可靠性。实现时做专门处理,提高执行效率和可靠性。用互斥信号量保护的代码区称作用互斥信号量保护的代码区称作“临界区临界区”,临界区,临界区代码通常用于对代码通常用于对共享资源共享资源的访问。的访问。互斥信号量的值被初始化成互斥信号量的值被初始化成1 1,表明目前没有任务进入,表明目前没有任务进入“临界区临界区”,但最多只有一个任务可以进入,但最多只有一个任务可以进入“临界临界区
6、区”。第一个试图进入第一个试图进入“临界区临界区”的任务将成功获得互斥信的任务将成功获得互斥信号量,而随后试图进入用同一信号量保护的临界区的号量,而随后试图进入用同一信号量保护的临界区的所有其他任务就必须等待。所有其他任务就必须等待。当任务离开当任务离开“临界区临界区”时,它将释放信号量并允许正时,它将释放信号量并允许正在等待该信号量的任务进入在等待该信号量的任务进入“临界区临界区”。互斥信号量互斥信号量Task1Task2共享资源共享资源互斥信号量互斥信号量 共享资源可能是一段存储器空间、一个数据结构共享资源可能是一段存储器空间、一个数据结构或或I/OI/O设备,也可能是被两个或多个并发任务
7、共享设备,也可能是被两个或多个并发任务共享的任何内容。的任何内容。使用互斥信号量可以实现对共享资源的串行访问,使用互斥信号量可以实现对共享资源的串行访问,保证只有成功地获取互斥信号量的任务才能够释保证只有成功地获取互斥信号量的任务才能够释放它。放它。互斥信号量是一种特殊的二值信号量,一般它支互斥信号量是一种特殊的二值信号量,一般它支持持所有权所有权、递归访问递归访问、任务删除安全任务删除安全和一些和一些避免避免优先级反转、饥饿、死锁等互斥所固有问题的协优先级反转、饥饿、死锁等互斥所固有问题的协议议。互斥信号量状态图互斥信号量状态图互斥信号量状态图互斥信号量状态图开启开启锁定锁定初始化初始化值为
8、值为1申请并获得申请并获得值为值为0释放释放值为值为1申请申请(递归递归)并获得并获得锁定数加锁定数加1释放释放(递归递归)锁定数减锁定数减1互斥信号量互斥信号量 所有权:当一个任务通过获取互斥信号量所有权:当一个任务通过获取互斥信号量而将其锁定时,得到该互斥信号量的所有而将其锁定时,得到该互斥信号量的所有权。相反,当一个任务释放信号量时,失权。相反,当一个任务释放信号量时,失去对其的所有权。去对其的所有权。当一个任务拥有互斥信号量时,其他的任当一个任务拥有互斥信号量时,其他的任务不能再锁定或释放它,即任务要释放互务不能再锁定或释放它,即任务要释放互斥信号量,必须事前先获取该信号量。斥信号量,
9、必须事前先获取该信号量。Task1RoutineARoutineB互斥信号量互斥信号量 嵌套(递归)资源访问嵌套(递归)资源访问 如果Task1调用RoutineA,而RoutineA又调用RoutineB,并且三者访问相同的共享资源,就发生了递归共享资源的访问同步问题。共享资源共享资源 一个递归的互斥信一个递归的互斥信号量允许嵌套锁定号量允许嵌套锁定互斥信号量,而不互斥信号量,而不引起死锁。引起死锁。互斥信号量互斥信号量 嵌套(递归)资源访问嵌套(递归)资源访问 每个获取信号量的调用必须与释放信号量的调用相匹配。当最外层的获取信号量的调用与释放信号量的调用匹配时,该信号量才允许被其它任务访问
10、。用于同步的信号量不支持嵌套访问,任务如果对同步信号量使用上述操作是错误的,任务会被永久阻塞,并且阻塞条件永远不会解除。互斥信号量互斥信号量 删除安全:删除安全:在一个受信号量保护的临界区,经常需要保护在临界区执行的任务不会被意外地删除。删除一个在临界区执行的任务可能引起意想不到的后果,造成保护资源的信号量不可用,可能导致资源处于破坏状态,也就导致了其它所有要访问该资源的任务无法得到满足。互斥信号量互斥信号量 删除安全:删除安全:为避免任务在临界区执行时不被意外删除:提供“任务保护”和“解除任务保护”原语对 同时,为互斥信号量提供“删除安全”选项。在创建信号量的时候使用这个选项,当应用每次获取
11、信号量时隐含地使能“任务保护”功能,当每次释放信号量时隐含地使用“解除任务保护”功能。各种互斥机制比较各种互斥机制比较比较项目比较项目关中断关中断使用测试并使用测试并置位指令置位指令禁止任务禁止任务切换切换使用信号量使用信号量锁定范围锁定范围互斥力度最强互斥力度最强,锁定所有外部可屏蔽中断,凡是以中断形式到达的外部事件以及与之相关联的任务或处理过程均得不到执行凡是使用该指令访问共享资源的代码所有的任务只影响竞争只影响竞争共享资源的共享资源的任务任务对系统响应对系统响应时间的影响时间的影响如果关中断的时间较长,对系统的响应性能有很大影响较小如果禁止切换的时间过长,则影响系统的响应性能对系统响应性
12、能对系统响应性能有一定影响,有一定影响,可可能导致优先级反能导致优先级反转转实现时的系实现时的系统开销统开销小小小较大较大注意事项注意事项关中断时间关中断时间要尽量短要尽量短不是所有的处理不是所有的处理器都具备这种指器都具备这种指令,影响可移植令,影响可移植性性关调度的时关调度的时间要尽量短间要尽量短需采用一定需采用一定的策略解决的策略解决优先级反转优先级反转问题问题二值信号量二值信号量 二值信号量主要用于二值信号量主要用于任务与任务之间任务与任务之间、任务与中任务与中断服务程序断服务程序之间的同步之间的同步 用于同步的二值信号量初始值为0,表示同步事件尚未产生;任务申请信号量以等待该同步事件
13、的发生;另一个任务或ISR到达同步点时,释放信号量(将其值设置为1)表示同步事件已发生,以唤醒等待的任务。Task1Task2二值信号量二值信号量初值为初值为0二值信号量二值信号量二值信号量状态图二值信号量状态图可获得可获得不可获得不可获得申请并获得申请并获得(值为值为0)释放释放(值为值为1)初始化初始化值为值为0Task1()执行一些操作执行一些操作;将信号量将信号量sem1置置1;申请信号量申请信号量sem2;Task2()申请信号量申请信号量sem1;执行一些操作执行一些操作;将信号量将信号量sem2置置1;Task2申请信号量申请信号量sem1失败,系统失败,系统切换到切换到Task
14、1s e m 1 被 置被 置 1 后,后,Task2得到得到sem1并并抢占抢占Task1Task2运行到某处运行到某处时因某种原因被时因某种原因被阻塞,系统切换阻塞,系统切换到到Task1计数信号量计数信号量 计数信号量用于控制系统中共享资源的多计数信号量用于控制系统中共享资源的多个实例的使用,允许多个任务同时访问同个实例的使用,允许多个任务同时访问同一种资源的多个实例一种资源的多个实例 计数信号量被初始化为计数信号量被初始化为n(非负整数),(非负整数),n为该种共享资源的数目。为该种共享资源的数目。Task1Task2共享资源实例共享资源实例nTask m共享资源实例共享资源实例1计数
15、信号量计数信号量计数信号量状态图计数信号量状态图可获得可获得不可获得不可获得初始化初始化值大于值大于0申请并获得申请并获得值为值为0释放释放值为值为1申请并获得申请并获得值减值减1释放释放值加值加1计数信号量计数信号量 1 2 3 4 n生产者任务生产者任务消费者任务消费者任务计数信号量使用实例:有界缓冲问题计数信号量使用实例:有界缓冲问题生产者任务生产者任务do 产生一个数据项产生一个数据项申请申请empty申请申请mutex将新生成的数据项添加到缓冲中将新生成的数据项添加到缓冲中释放释放mutex释放释放full while(1);消费者任务消费者任务do 申请申请full申请申请mute
16、x从缓冲中移出一个数据项的内容从缓冲中移出一个数据项的内容释放释放mutex释放释放empty消费新获得的数据项内容消费新获得的数据项内容 while(1);计数信号量计数信号量full:已被填充的数据项数目,取值范围:已被填充的数据项数目,取值范围0n,初始值为,初始值为0计数信号量计数信号量empty:空闲数据项数目,取值范围为:空闲数据项数目,取值范围为0n,初始值为,初始值为n;互斥信号量互斥信号量mutex:控制生产者任务和消费者任务对有界缓冲的访问,:控制生产者任务和消费者任务对有界缓冲的访问,初始值为初始值为1。信号量机制的主要数据结构信号量机制的主要数据结构SCB1SCB2信号
17、量控制块信号量控制块count信号量名字或信号量名字或IDTask1Task2任务等待列表任务等待列表信号量机制的主要数据结构信号量机制的主要数据结构 信号量控制块信号量控制块:管理所有创建的信号量,内核:管理所有创建的信号量,内核在系统运行时动态分配和回收信号量控制块在系统运行时动态分配和回收信号量控制块 互斥和二值信号量控制块结构互斥和二值信号量控制块结构:Binary_Semaphore_Control_BlockBinary_Semaphore_Control_Blockwait_queue任务等待队列任务等待队列attributes信号量属性信号量属性lock_nesting_beh
18、avior试图嵌套获得时的规则试图嵌套获得时的规则 wait_discipline任务等待信号量的方式任务等待信号量的方式priority_ceiling优先级天花板值优先级天花板值lock是否被占有是否被占有holder拥有者拥有者 nest_count嵌套层数嵌套层数 计数信号量控制结构计数信号量控制结构Counting_Semaphore_Control_BlockCounting_Semaphore_Control_Block wait_queuewait_queue 任务等待队列任务等待队列 attributes attributes 计数信号量属性计数信号量属性 maximum_c
19、ountmaximum_count 最大计数值最大计数值 wait_discipline wait_discipline任务等待信号量的方式任务等待信号量的方式 count count当前计数值当前计数值信号量机制的主要数据结构信号量机制的主要数据结构信号量内部实现机制实例说明信号量内部实现机制实例说明C/OS-II 事件控制块事件控制块ECBECB同步与通信机制的基本数据结构同步与通信机制的基本数据结构typedef structtypedef structINT8UOSEventType;/事件类型INT8UOSEventGrp;/等待任务所在的组INT16UOSEventCnt;/计数器
20、(信号量)void*OSEventPtr;/指向消息或消息队列的指针INT8UOSEventTblOS_EVENT_TBL_SIZE;/等待任务列表OS_EVENT;OS_EVENT;信号量内部实现机制实例说明信号量内部实现机制实例说明C/OS-II 当一个事件发生当一个事件发生后,等待事件列后,等待事件列表中优先级最高表中优先级最高的任务(即的任务(即在在.OSEventTbl.OSEventTbl&OSEventGrp&OSEventGrp中所中所有被置有被置1 1的位中优的位中优先级数值最小的先级数值最小的任务)得到该事任务)得到该事件。件。信号量内部实现机制实例说明信号量内部实现机制实
21、例说明C/OS-II 当当.OSEventTbln.OSEventTbln中的任何一位为中的任何一位为1 1时,时,OSEventGrpOSEventGrp中的第中的第n n位为位为1 1。与任务就绪列与任务就绪列表类似!表类似!信号量内部实现机制实例说明信号量内部实现机制实例说明C/OS-II 将一个任务插入到等待事件将一个任务插入到等待事件的任务列表中:的任务列表中:pevent-OSEventGrp|=OSMapTblprio 3;pevent-OSEventTblprio 3|=OSMapTblprio&0 x07;与将一个任务插入到就绪列表中的操作类似!Index Bit mask(
22、Binary)0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 1 02 0 0 0 0 0 1 0 03 0 0 0 0 1 0 0 04 0 0 0 1 0 0 0 05 0 0 1 0 0 0 0 06 0 1 0 0 0 0 0 07 1 0 0 0 0 0 0 0信号量内部实现机制实例说明信号量内部实现机制实例说明C/OS-II 从等待事件的任务列表中使任务脱离等待从等待事件的任务列表中使任务脱离等待状态状态if(pevent-OSEventTblprio 3&=OSMapTblprio&0 x07)=0)pevent-OSEventGrp&=OSMapTblprio 3
23、;与将任务从就绪列表中清除的操作类似!信号量内部实现机制实例说明信号量内部实现机制实例说明C/OS-II 在等待事件的任务列表中查找优先级最高在等待事件的任务列表中查找优先级最高的任务的任务y=OSUnMapTblpevent-OSEventGrp;x=OSUnMapTblpevent-OSEventTbly;prio=(y OSEventPtr;)OSEventFreeList-OSEventPtr;if(pevent!=(OS_EVENT if(pevent!=(OS_EVENT*)0)0)/初始化初始化ECBECB的各个域的各个域pevent-OSEventType=OS_EVENT_T
24、YPE_SEM;pevent-OSEventType=OS_EVENT_TYPE_SEM;/事件类型为事件类型为信号量信号量pevent-OSEventCnt=cnt;pevent-OSEventCnt=cnt;/信号量的初始计数值信号量的初始计数值pevent-OSEventPtr=(void pevent-OSEventPtr=(void*)0;)0;OS_EventWaitListInit(pevent);OS_EventWaitListInit(pevent);/初始化等待任务列表初始化等待任务列表 return(pevent);return(pevent);/调用者需检查返回值,如果
25、为调用者需检查返回值,如果为NULLNULL则表示建立则表示建立失败失败 获取(申请)信号量获取(申请)信号量 功能:试图获得应用指定的信号量。功能:试图获得应用指定的信号量。if 信号量的值大于0then 将信号量的值减1else 根据接收信号量的选项,将任务放到等待队列中,或是直接返回获取(申请)信号量获取(申请)信号量 当所申请的信号量不能被立即获得时,可当所申请的信号量不能被立即获得时,可以有以下几种选择:以有以下几种选择:永远等待 不等待,立即返回,并返回一个错误状态码 指定等待时限(可有效避免死锁)注意:不允许在ISR中选择等待 当任务选择等待时,将被按FIFO或优先级顺序放置在等
26、待队列中获取(申请)信号量获取(申请)信号量 如果任务等待一个使用如果任务等待一个使用优先级继承算法优先级继承算法的互斥的互斥信号量,且它的优先级高于当前正占有此信号信号量,且它的优先级高于当前正占有此信号量的任务的优先级,那么占有信号量的任务将量的任务的优先级,那么占有信号量的任务将继承这个被阻塞的任务的优先级。继承这个被阻塞的任务的优先级。如果任务成功地获得一个采用如果任务成功地获得一个采用优先级天花板算优先级天花板算法法的互斥信号量,它的优先级又低于优先级天的互斥信号量,它的优先级又低于优先级天花板,那么它的优先级将被抬升至天花板。花板,那么它的优先级将被抬升至天花板。获取(等待)一个信
27、号量获取(等待)一个信号量OSSemPend()void OSSemPend(OS_EVENT void OSSemPend(OS_EVENT*pevent,INT16U timeout,INT8U pevent,INT16U timeout,INT8U*err)err)if(pevent-OSEventCnt 0)if(pevent-OSEventCnt 0)/信号量值大于信号量值大于0 0,成功获得信号量并返回,成功获得信号量并返回pevent-OSEventCnt-;pevent-OSEventCnt-;*err=OS_NO_ERR;err=OS_NO_ERR;return;return
28、;OSTCBCur-OSTCBStat|=OS_STAT_SEM;OSTCBCur-OSTCBStat|=OS_STAT_SEM;/设置任务状态为等待信号量设置任务状态为等待信号量OSTCBCur-OSTCBDly=timeout;OSTCBCur-OSTCBDly=timeout;/设置等待时限设置等待时限OS_EventTaskWait(pevent);OS_EventTaskWait(pevent);/将任务放置到信号量的等待列表中将任务放置到信号量的等待列表中 OS_Sched();OS_Sched();/内核实施任务调度,系统切换到另一就绪任务执行内核实施任务调度,系统切换到另一就绪
29、任务执行if(OSTCBCur-OSTCBStat&OS_STAT_SEM)if(OSTCBCur-OSTCBStat&OS_STAT_SEM)/判断任务恢复执行的原因,判断任务恢复执行的原因,如果等待时限超时但仍然未获得信号量,则返回超时信息如果等待时限超时但仍然未获得信号量,则返回超时信息OSEventTO(pevent);OSEventTO(pevent);*err=OS_TIMEOUT;err=OS_TIMEOUT;return;return;OSTCBCur-OSTCBEventPtr=(OS_EVENT OSTCBCur-OSTCBEventPtr=(OS_EVENT*)0;)0;
30、*err=OS_NO_ERR;err=OS_NO_ERR;/任务由于获得信号量而恢复执行,本调用成功返回任务由于获得信号量而恢复执行,本调用成功返回 获取(无等待地请求)一个信号量获取(无等待地请求)一个信号量OSSemAccept()INT16U OSSemAccept(OS_EVENT INT16U OSSemAccept(OS_EVENT*pevent)pevent)INT16U cnt;INT16U cnt;cnt=pevent-OSEventCnt;cnt=pevent-OSEventCnt;if(cnt 0)if(cnt 0)pevent-OSEventCnt-;pevent-OS
31、EventCnt-;return(cnt);return(cnt);注意:即使不能成功获得信号量(返回值为注意:即使不能成功获得信号量(返回值为0 0),调用者),调用者也不会被阻塞。此函数可以在中断处理程序中使用。也不会被阻塞。此函数可以在中断处理程序中使用。释放信号量释放信号量 功能:释放一个应用指定的信号量。功能:释放一个应用指定的信号量。if 没有任务等待这个信号量then 信号量的值加1 else 将信号量分配给一个等待任务(将相应的任务移出等待队列,使其就绪)如果使用了如果使用了优先级继承优先级继承或或优先级天花板优先级天花板算算法,那么执行该功能(系统调用)的任务法,那么执行该功
32、能(系统调用)的任务的优先级将恢复到原来的高度。的优先级将恢复到原来的高度。释放一个信号量释放一个信号量OSSemPost()INT8U OSSemPost(OS_EVENT INT8U OSSemPost(OS_EVENT*pevent)pevent)if(pevent-OSEventGrp!=0 x00)if(pevent-OSEventGrp!=0 x00)/如果有任务在等待该信号量如果有任务在等待该信号量OS_EventTaskRdy(pevent,(void OS_EventTaskRdy(pevent,(void*)0,OS_STAT_SEM);)0,OS_STAT_SEM);/使
33、等使等待任务列表中优先级最高的任务就绪待任务列表中优先级最高的任务就绪OS_Sched();OS_Sched();/内核实施任务调度内核实施任务调度return(OS_NO_ERR);return(OS_NO_ERR);/成功返回成功返回 if(pevent-OSEventCnt OSEventCnt OSEventCnt+;pevent-OSEventCnt+;/信号量的值加信号量的值加1 1return(OS_NO_ERR);return(OS_NO_ERR);/成功返回成功返回 return(OS_SEM_OVF);return(OS_SEM_OVF);/信号量溢出信号量溢出 删除信号量
34、删除信号量 功能:从系统中删除应用指定的一个信号功能:从系统中删除应用指定的一个信号量量 内核动作:将信号量控制块返还给系统内核动作:将信号量控制块返还给系统 删除信号量的不一定是创建信号量的任务删除信号量的不一定是创建信号量的任务 如果有任务正在等待获得该信号量,执行如果有任务正在等待获得该信号量,执行此功能将使所有等待这个信号量的任务回此功能将使所有等待这个信号量的任务回到就绪队列中,且返回一个状态码指示该到就绪队列中,且返回一个状态码指示该信号量已被删除信号量已被删除删除信号量删除信号量 企图获取已删除的信号量将返回一个错误;企图获取已删除的信号量将返回一个错误;在互斥信号量正被使用时(
35、已经被某任务在互斥信号量正被使用时(已经被某任务获取),不能删除它。因为该信号量正在获取),不能删除它。因为该信号量正在保护一个共享资源或临界代码段,该动作保护一个共享资源或临界代码段,该动作可能造成数据崩溃或其他严重问题。可能造成数据崩溃或其他严重问题。删除一个信号量删除一个信号量OSSemDel()OS_EVENT OS_EVENT*OSSemDel(OS_EVENT OSSemDel(OS_EVENT*pevent,INT8U opt,INT8U pevent,INT8U opt,INT8U*err)err)BOOLEAN tasks_waiting;BOOLEAN tasks_wait
36、ing;if(pevent-OSEventGrp!=0 x00if(pevent-OSEventGrp!=0 x00/根据是否有任务在等待信号量设置等待标根据是否有任务在等待信号量设置等待标志志tasks_waiting=TRUE;tasks_waiting=TRUE;elseelsetasks_waiting=FALSE;tasks_waiting=FALSE;switch(opt)switch(opt)case OS_DEL_NO_PEND:case OS_DEL_NO_PEND:/如果有任务等待信号量则不删除信号量如果有任务等待信号量则不删除信号量if(task_waiting=FALS
37、Eif(task_waiting=FALSE/没有任务等待,释放没有任务等待,释放ECBECB回空闲链回空闲链pevent-OSEventType=OS_EVENT_TYPE_UNUSED;pevent-OSEventType=OS_EVENT_TYPE_UNUSED;pevent-OSEventPtr=OSEventFreeList;pevent-OSEventPtr=OSEventFreeList;OSEventFreeList=pevent;OSEventFreeList=pevent;/调整空闲调整空闲ECBECB链头指针链头指针*err=OS_NO_ERR;err=OS_NO_ERR
38、;return(OS_EVENT)0);return(OS_EVENT)0);elseelse*err=OS_ERR_TASK_WAITING;err=OS_ERR_TASK_WAITING;/有任务等待,删除信有任务等待,删除信号量失败号量失败return(pevent);return(pevent);删除一个信号量删除一个信号量OSSemDel()case OS_DEL_ALWAYS:case OS_DEL_ALWAYS:/无论有无任务等待都删除信号量无论有无任务等待都删除信号量 /将等待列表中的每个任务都设置成就绪将等待列表中的每个任务都设置成就绪while(pevent-OSEvent
39、Grp!=0 x00)while(pevent-OSEventGrp!=0 x00)OS_EventTaskRdy(pevent,(void OS_EventTaskRdy(pevent,(void*)0,OS_STAT_SEM);)0,OS_STAT_SEM);/释放该信号量的释放该信号量的ECBECB回空闲控制块链回空闲控制块链pevent-OSEventType=OS_EVENT_TYPE_UNUSED;pevent-OSEventType=OS_EVENT_TYPE_UNUSED;pevent-OSEventFreeList;pevent-OSEventFreeList;OSEvent
40、FreeList=pevent;OSEventFreeList=pevent;/如果之前有任务等待信号量,内核实施任务调度如果之前有任务等待信号量,内核实施任务调度if(tasks_waiting=TRUE)OS_Sched();if(tasks_waiting=TRUE)OS_Sched();*err=OS_NO_ERR;err=OS_NO_ERR;return(OS_EVENT return(OS_EVENT*)0);)0);default:default:*err=OS_ERR_INVALID_OPT;err=OS_ERR_INVALID_OPT;return(pevent);retur
41、n(pevent);清除信号量的任务等待列表清除信号量的任务等待列表 为了清除等待一个信号量的所有任务,某为了清除等待一个信号量的所有任务,某些内核支持些内核支持FlushFlush操作,以便释放信号量等操作,以便释放信号量等待任务列表中的所有任务。当多个任务的待任务列表中的所有任务。当多个任务的执行必须在某些点相遇时,需要这样的机执行必须在某些点相遇时,需要这样的机制。制。SignalTaskTask2 二值信号量二值信号量初值为初值为0FlushTask1Task3第二节第二节邮箱和消息队列邮箱和消息队列通信方式概述通信方式概述消息队列机制的主要数据结构消息队列机制的主要数据结构典型的消息
42、队列操作典型的消息队列操作消息队列的其他典型使用消息队列的其他典型使用 任务间的通信方式任务间的通信方式 直接通信。在通信过程中双方必须明确地知道(命名)彼此:Send(P,message)发送一个消息到任务P Receive(Q,message)从任务Q接收一个消息 间接通信。通信双方不需要指出消息的来源或去向,而通过中间机制来通信。如:send(A,message)发送一个消息给邮箱A receive(A,message)从邮箱A接收一个消息通信方式概述通信方式概述 消息队列:消息队列:属于间接通信方式属于间接通信方式 消息:消息:内存空间中一段长度可变的缓冲区,其内存空间中一段长度可变的
43、缓冲区,其长度和内容均可以由用户定义,其内容可以是长度和内容均可以由用户定义,其内容可以是实际的数据、数据块的指针或空。实际的数据、数据块的指针或空。对消息内容的解释由应用完成。对消息内容的解释由应用完成。从操作系统操作系统观点看,消息没有定义的格式,所有的消息都是字节流,没有特定的含义。从应用应用观点看,根据应用定义的消息格式,消息被解释成特定的含义。应用可以只把消息当成一个标志,这时消息机制用于实现同步同步概述概述 一些操作系统内核把消息进一步分为:邮箱和一些操作系统内核把消息进一步分为:邮箱和消息队列消息队列 邮箱仅能存放单条消息,它提供了一种低开销的机制来传送信息。每个邮箱可以保存一条
44、大小为若干个字节的消息。消息队列可存放若干消息,提供了一种任务间缓冲通信的方法。消息机制可支持消息机制可支持定长定长与与可变长度可变长度两种模式的消两种模式的消息,可变长度的消息队列需要对队列中的每一息,可变长度的消息队列需要对队列中的每一条消息增加额外的存储开销。条消息增加额外的存储开销。概述概述消息队列机制的主要数据结构消息队列机制的主要数据结构队列控制块队列控制块队列长度队列长度QCB1队列名或队列名或IDTask3Task4接收任务等待列接收任务等待列表表Task1Task2发送任务等待列发送任务等待列表表最大最大消息消息长度长度QCB2消息队列及其相关的参数和支持数据结构消息队列及其
45、相关的参数和支持数据结构 消息队列状态图消息队列状态图非空非空满满队列创建队列创建消息数为消息数为0消息队列状态图消息队列状态图消息发送消息发送消息数加消息数加1空空消息发送消息发送消息数为消息数为1消息接收消息接收消息数为消息数为0消息接收消息接收消息数减消息数减1消息接收消息接收消息数减消息数减1消息发送消息发送消息数等于队列长度消息数等于队列长度消息队列机制的主要数据结构消息队列机制的主要数据结构 消息队列控制块消息队列控制块 管理所有创建的消息队列,系统运行时动态分配和回收消息队列控制块 消息队列缓冲区消息队列缓冲区 存放发送到该队列的消息,接收者从缓冲区中取出消息。消息的发送或接收有
46、两种方法(影响消息缓冲区结构):将数据从发送任务的空间完全拷贝到接收任务的空间中(效率较低,执行时间与消息大小有关)只传递指向数据存储空间的指针(提高系统性能)Sending TaskReceiving TaskMessage1Message1Message1发送任务的发送任务的内存区域内存区域消息队列的消息队列的内存区域内存区域接收任务的接收任务的内存区域内存区域1st copy2nd copynumber_of_messagemax_message_countnumber_of_messagemax_message_sizewait_disciplinewait_queuequeue_st
47、artqueue_inqueue_outqueue_endmessagemessagemessagemessagemessagemessagemessagemessagemessagemax_message_count消息队列消息队列控制块控制块消息队列消息队列缓冲区缓冲区消息队列机制的主要数据结构消息队列机制的主要数据结构消息队列机制的主要数据结构消息队列机制的主要数据结构max_message_countqueue_endqueue_startqueue_outnumber_of_messagequeue_in消息指针消息指针典型的消息队列操作典型的消息队列操作 创建消息队列创建消息队列
48、发送普通消息发送普通消息 发送紧急消息发送紧急消息 发送广播消息发送广播消息 接收消息接收消息 删除消息队列删除消息队列 获取有关消息队列的各种信息获取有关消息队列的各种信息 创建消息队列创建消息队列 创建消息队列时,调用者可以指定如下参创建消息队列时,调用者可以指定如下参数:数:消息的最大长度 每个消息队列中最多的消息数 消息队列的属性 任务等待消息时的排队方式:FIFO或PRIORITY 系统为新创建的消息队列分配唯一的系统为新创建的消息队列分配唯一的ID ID 发送消息发送消息 根据紧急程度的不同,消息通常可分为根据紧急程度的不同,消息通常可分为普通消息普通消息与与紧急消息紧急消息。如果
49、有任务正在等待消息(即消息队列为空),则普通消息发送和紧急消息发送的执行效果是一样的。任务从等待队列移到就绪队列中,消息被拷贝到任务提供的缓冲区中(或者由接收任务得到指向消息的指针)。如果没有任务等待,发送普通消息将消息放在队列尾,而发送紧急消息将消息放在队列头。发送消息发送消息Msg 3接收任务接收任务等待列表等待列表Msg 2Msg 1消息队列消息队列发送普通消息先进先出发送普通消息先进先出(FIFO)次序)次序Msg 3接收任务接收任务等待列表等待列表Msg 2Msg 1消息队列消息队列发送紧急消息后进先出发送紧急消息后进先出(LIFO)次序)次序发送消息发送消息 如果发送消息时如果发送
50、消息时队列已被填满队列已被填满,则不同的操作,则不同的操作系统可能采取不同的处理办法:系统可能采取不同的处理办法:挂起试图向已满的消息队列中发送消息的任务(不适用于中断服务程序)简单地丢弃该条消息并向调用者返回错误信息 广播消息广播消息。在此之前所有试图从队列中接收消。在此之前所有试图从队列中接收消息的任务此时都将获得相同的消息。该功能拷息的任务此时都将获得相同的消息。该功能拷贝消息到各任务的消息缓冲中(或者让所有的贝消息到各任务的消息缓冲中(或者让所有的等待任务得到指向消息的指针),并唤醒所有等待任务得到指向消息的指针),并唤醒所有的等待任务。的等待任务。接收消息接收消息 如果指定的消息队列
侵权处理QQ:3464097650--上传资料QQ:3464097650
【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。