任务的同步与通信

任务间的同步

在多任务合作工作过程中,操作系统要解决两个问题:

  • 各任务间应该具有一种互斥关系,即对某些共享资源,如果一个任务正在使用,则其他任务只能等待,等到该任务释放资源后,等待任务之一才能使用它;
  • 相关的任务在执行上要有先后次序,一个任务要等其伙伴发来通知,或建立了某个条件后才能继续执行,否则只能等待;

任务之间的这种制约性的合作运行机制叫任务间的同步;

任务中的事件

uCosII使用信号量、消息邮箱和消息队列这些中间环节来实现任务之间的通信,而这些中间环节都统一称为事件;

事件控制块及事件处理

事件控制块

对于事件来说,当其被占用时,会导致其他请求该事件的任务因暂时得不到该事件的服务而处于等待状态;

作为功能完善的事件,应该对这些等待任务有两方面的管理能力:

  • 要对等待事件的所有任务进行记录并排序;
  • 允许等待任务有一个等待时限,即当等待任务认为等不及时可以退出对事件的请求;

对于等待事件任务的记录,系统定义了一个INT8U类型的数组OSEventTbl[]作为等待事件任务的记录表,即等待任务表;

等待任务表以任务优先级别为顺序为每个任务分配一个二进制位,来表示这一位对应的任务为事件的等待任务,否则不是等待任务;

为了加快该表的访问速度,也定义了一个INT8U类型的变量OSEventGrp来表示等待任务中的任务组;

等待任务的等待时限记录在等待任务的任务控制块TCB的成员OSTCBDly中,并在每个时钟节拍中断服务程序中对该数据进行维护,每当有任务的等待时限到达时,便将该任务从等待任务表中删除,并使它进入就绪状态;

系统为了把描述事件的数据结构统一起来,使用叫做事件控制快ECB的数据结构来描述诸如信号量、消息邮箱和消息队列等事件;

事件控制块的组织是通过事件控制块链表的形式;

事件处理函数

系统中对事件控制块进行基本操作的函数定义在文件os_core.c中;

  • EventWaitListInit()事件控制块的初始化函数,作用是把变量OSEventGrp及任务等待表中的每一位都清0,即令事件任务等待表中不含有任何等待任务;
  • OS_EventTaskWait()把一个任务置于等待状态;
  • OS_EventTaskRdy()把调用这个函数的任务在任务等待表中的位置清0(解除等待状态)后,再把任务在任务就绪表中对应的位置设置为1,然后引发一次任务调度;
  • OS_EventTO()使一个等待超时的任务进入就绪状态;

信号量及其操作

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

信号量由计数器和等待任务表两部分组成;

操作

OSSemCreate

应用程序在使用信号量之前必须先调用该函数来创建一个信号量;

OSSemPend

请求信号量,为防止任务因得不到信号量而处于长期的等待状态,该函数允许用参数timeout设置一个等待时间的限制,当任务等待时间超过timeout时,可以结束等待状态而进入就绪状态,如果该参数设置为0,则表明任务的等待时间为无限长;

当任务需要访问一个共享资源时,先要请求管理该资源的信号量,这样就可以根据信号量当前是否有效(即信号量计数器的值是否大于0)来决定该任务是否可以继续运行,如果信号量有效,则把信号量计数器减1,然后继续运行任务,如果信号量无效(即信号量计数器的值等于0),则会在等待任务表中把该任务对应的位设置为1而让任务处于等待状态,并把等待时限timeout保存在任务控制块对应的变量中;

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

OSSemPost

任务获得信号量,在访问共享资源结束以后,必须调用该函数释放信号量,也叫发送信号量;

该函数在对信号量的计数器操作之前,要检查是否还有等待该信号量的任务,如果没有,则将信号量计数器值加1,如果有,则调用调度器OS_Sched()去运行等待任务中优先级最高的任务;

OSSemDel

如果应用程序不需要某个信号,那么可调用该函数来删除该信号;

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

  • OS_DEL_NO_PEND当等待任务表中已没有等待任务时才删除信号量;
  • OS_DEL_ALLWAYS在等待任务表中无论是否有等待任务都立即删除信号量;

需要注意,只能在任务中删除信号量,而不能在中断服务程序中删除;

OSSemQuery

任务可以调用该函数随时查询信号量的当前状态;

互斥信号量

互斥信号量时一个二值信号,可以使任务以独占方式使用共享资源;

使用互斥型信号量会出现任务优先级反转的问题,即在可剥夺型内核中,当任务以独占方式使用共享资源时,会出现低优先级任务先于高优先级任务而被运行的现象,这种现象在实时系统中是不允许出现的,因为它破坏了任务执行的预期顺序,可能会导致严重的后果;

解决该现象的办法之一是,使获得信号量任务的优先级别在使用共享资源期间暂时提升到所有任务最高优先级的高一个级别上,以使该任务不被其他任务所打断,从而能尽快地使用完共享资源并释放信号量,然后在释放信号量之后,再恢复该任务原来的优先级别;

OSMutexCreate

创建互斥型信号量,在描述互斥型信号量的事件控制块中,除了成员OSEventType要赋予常数OS_EVENT_TYPE_MUTEX以表明是一个互斥型信号量和仍然没有使用成员OSEventPtr之外,成员OSEventCnt被分成了低8位和高8位两部分,高8位用来存放为了避免出现优先级反转现象而要提升的优先级prio,低8位赋予常数OS_MUTEX_AVAILABLE,表明信号量尚未被任何任务所占用,处于有效状态;

OSMutexPend

请求互斥型信号量;

也可以调用函数OSMutexAccept()无等待地请求一个互斥型信号量;

OSMutexPost

发送一个互斥型信号量;

OSMutexQuery

获取互斥型信号量的当前状态;

OSMutexDel

任务调用该函数可删除一个互斥型信号量;

消息邮箱

OSMboxCreate

创建消息邮箱;

OSMboxPost

向消息邮箱发送消息;

OSMboxPostOpt

向消息邮箱发送消息,可以以广播的方式向事件等待任务表中的所有任务发送消息;

OSMboxPend

请求消息邮箱;

OSMboxAccept

请求消息邮箱失败时,不进行等待而是继续运行;

OSMboxQuery

查询消息邮箱当前状态信息;

OSMboxDel

删除一个消息邮箱;

消息队列

使用消息队列可在任务之间传递多条消息,消息队列由三部分组成:时间控制块、消息队列和消息;

事件控制块成员OSEventPtr指向一个叫做队列控制块(OS_Q)的结构,该结构管理着一个数组MsgTbl[],该数组中的元素都是指向消息的指针;

OSQCreate

创建消息队列,首先需要定义一个指针数组,然后把各个消息数据缓冲区的首地址存入这个数组中,最后调用该函数来创建消息队列;

OSQPend

请求消息队列,即从消息队列中获取消息;

如果希望任务无等待地请求一个消息队列,则可调用函数OSQAccept()函数;

OSQPost/OSQPostFront

向消息队列发送消息;

函数OSQPost()是以FIFO的方式组织消息队列;

函数OSQPostFront()以LIFO的方式组织消息队列;

OSQPostOpt

该函数时任务将以广播的方式通过消息队列发送消息;

OSQFlush

清空消息队列;

OSQDel

删除一个已存在的消息队列;

OSQQuery

查询一个消息队列的状态;

uCos-II中任务的同步与通信的更多相关文章

  1. ucos ii 百度官方介绍

          μC/OS II(Micro-Controller Operating System Two)是一个可以基于ROM运行的.可裁剪的.抢占式.实时多任务内核,具有高度可移植性,特别适合于微处 ...

  2. ucos实时操作系统学习笔记——任务间通信(队列)

    ucos操作系统中的queue机制同样使用了event机制来实现,其实和前面的sem,mutex实现类似,所不同的是对sem而言,任务想获得信号量,对mutex而言,任务想获得的是互斥锁.任务间通信的 ...

  3. DE1-SOC开发板上搭建NIOS II处理器运行UCOS II

    DE1-SOC开发板上搭建NIOS II处理器运行UCOS II   今天在DE1-SOC的开发板上搭建NIOS II软核运行了UCOS II,整个开发过程比较繁琐,稍微有一步做的不对,就会导致整个过 ...

  4. [转]在Windows中配置Rsync同步

    在Windows中配置Rsync同步 Rsync是一款不错的文件免费同步软件,可以镜像保存整个目录树和文件系统,同 时保持原来文件的权限.时间.软硬链接.第一次同步时 rsync 会复制全部内容,下次 ...

  5. Win32多线程编程(3) — 线程同步与通信

      一.线程间数据通信 系统从进程的地址空间中分配内存给线程栈使用.新线程与创建它的线程在相同的进程上下文中运行.因此,新线程可以访问进程内核对象的所有句柄.进程中的所有内存以及同一个进程中其他所有线 ...

  6. US/OS2之任务同步与通信

    嵌入式系统中的各个任务都是以并发的方式来运行的,并为同一个大的任务服务,它们不可避免地要共同使用一些共享资源,并且在处理一些需要多个任务共同协作来完成的工作时,还需要相互的支持和限制.因此,对于一个完 ...

  7. javaEE开发中使用session同步和token机制来防止并发重复提交

    javaEE开发中使用session同步和token机制来防止并发重复提交 通常在普通的操作当中,我们不需要处理重复提交的,而且有很多方法来防止重复提交.比如在登陆过程中,通过使用redirect,可 ...

  8. Python 多线程、多进程 (二)之 多线程、同步、通信

    Python 多线程.多进程 (一)之 源码执行流程.GIL Python 多线程.多进程 (二)之 多线程.同步.通信 Python 多线程.多进程 (三)之 线程进程对比.多线程 一.python ...

  9. Qt 多线程同步与通信

    Qt 多线程同步与通信 1 多线程同步 Qt提供了以下几个类来完成这一点:QMutex.QMutexLocker.QSemphore.QWaitCondition. 当然可能还包含QReadWrite ...

随机推荐

  1. 使用make

    5.11 库的使用 代码的复用是计算机程序设计语言中的一个重要的概念.可以把编译好的目标文件模块统一放到一个库中,使得程序员可以在不同的程序中共享这些代码. 在Linux操作系统下,最后连接生成可执行 ...

  2. CentOS 6忘记root密码的解决办法

    1.在开机启动的时候按键盘上的“E”键 或者“ESC”键,会进入如下界面 2.选择相应的内核,再次按“E”,出现下图,选择第二项,再次按“E”键 3.经过第二步,这个画面可以编辑,在信息的最后加“空格 ...

  3. June. 26th 2018, Week 26th. Tuesday

    No affection but interests can be found in the world of animals. 在动物的世界里,只有利益,没有感情. From Animal Worl ...

  4. 【原创】从Rest到Graphql

    引言 开局两张图,内容全靠编- ok,如图所示,我在去年曾经写过一篇文章<闲侃前后端分离的必要性>.嗯,我知道肯定很多人没看过.所以我做一个总结,其实啰里八嗦了一篇文章,就是想说一下现在的 ...

  5. ABP之什么是ABP(ASP.NET Boilerplate)

    1.介绍 ABP是开源的且文档比较齐全的应用程序框架.其实它不仅仅是个框架,考虑其最佳实践,ABP更提供了基于领域驱动设计(DDD)的强大价格模型. ABP支持最新的ASP.NET Core和EF C ...

  6. App Inventor2项目部署到本地

    介绍App Inventor App Inventor 原是Google实验室(Google Lab)的一个子计划,该项目是一个完全在线开发的Android编程环境,抛弃复杂的程式代码而使用积木式的堆 ...

  7. elk部署之前注意事项

    注意事项: 1.不能使用root用户登录,需要是用root 之外的用户登录到系统. 2.centos系统 运行内存不能小于2G,若低于2G需要修改jvm. vi  {jvm_home}/config/ ...

  8. 三、Redis基础操作

    前言: Redi是key-value的NoSQL,我们用Redis提供的redis-cli就能操作String类型key和各种数据类型value.但是放入的不是特定类型数据,添加的都是一个一个Stri ...

  9. admin 配置

    如何创建admin管理员 python manage.py createsuperuser #这里要注意python是环境变量中你设置的名字也可能是python2,python3 admin编程中文环 ...

  10. 关系型数据库 VS 非关系型数据库

    一.关系型数据库? 1.概念 关系型数据库是指采用了关系模型来组织数据的数据库.简单来说,关系模式就是二维表格模型. 主要代表:SQL Server,Oracle,Mysql,PostgreSQL. ...