您好、欢迎来到现金彩票网!
当前位置:秒速牛牛开奖 > 同步通信量 >

RT-Thread 03任务间同步及通讯 -中断关闭、调度器锁、信号量

发布时间:2019-07-21 18:42 来源:未知 编辑:admin

  RT-Thread 03任务间同步及通讯 -中断关闭、调度器锁、信号量

  在多任务实时系统中,一项工作的完成往往可以通过多个任务协调的方式共同来完成, 例如一个任务从传感器中接收数据并且将数据写到共享内存中,同时另一个任务周期性的从共享内存中读取数据并发送去显示(如图 两个线程间的数据传递 )

  如果对共享内存的访问不是排他性的,那么各个线程间可能同时访问它。这将引起数据一致性的问题,例如,在显示线程试图显示数据之前,传感器线程还未完成数据的写入,那么显示将包含不同时间采样的数据,造成显示数据的迷惑。 将传感器数据写入到共享内存的代码是接收线程的关键代码段;将传感器数据从共享内存中读出的代码是显示线程的关键代码段;这两段代码都会访问共享内存。正常的操作序列应该是在一个线程对共享内存块操作完成后,才允许另一个线程去操作。对于操作/访问同一块区域,称之为临界区。 任务的同步方式有很多种,其核心思想都是:在访问临界区的时候只允许一个(或一类)任务运行。

  关闭中断也叫中断锁,是禁止多任务访问临界区最简单的一种方式,即使是在分时操作系统中也是如此。当中断关闭的时候,就意味着当前任务不会被其他事件打断(因为整个系统已经不再响应那些可以触发线程重新调度的外部事件),也就是当前线程不会被抢占,除非这个任务主动放弃了处理器控制权。关闭中断/恢复中断API接口由BSP实现,根据平台的不同其实现方式也大不相同。

  警告:由于关闭中断会导致整个系统不能响应外部中断,所以在使用关闭中断做为互斥访问临界区的手段时,首先必须需要保证关闭中断的时间非常短,例如数条机器指令。

  使用中断锁来操作系统的方法可以应用于任何场合,且其他几类同步方式都是依赖于中断锁而实现的,可以说中断锁是最强大的和最高效的同步方法。只是使用中断锁最主要的问题在于,在中断关闭期间系统将不再响应任何中断,也就不能响应外部的事件。所以中断锁对系统的实时性影响非常巨大,当使用不当的时候会导致系统完全无实时性可言(可能导致系统完全偏离要求的时间需求);而使用得当,则会变成一种快速、高效的同步方式。 例如,为了保证一行代码(例如赋值)的互斥运行,最快速的方法是使用中断锁而不是信号量或互斥量:

  level = rt_hw_interrupt_disable(); a = a +

  在使用中断锁时,需要确保关闭中断的时间非常短,例如上面代码中的a = a + value; 也可换成另外一种方式,例如使用信号量:

  rt_sem_take(sem_lock, RT_WAITING_FOREVER); a = a +

  这段代码在rt_sem_take 、rt_sem_release 的实现中,已经存在使用中断锁保护信号量内部变量的行为,所以对于简单如a = a + value;的操作,使用中断锁将更为简洁快速。

  同中断锁一样把调度器锁住也能让当前运行的任务不被换出,直到调度器解锁。但和中断锁有一点不相同的是,对调度器上锁,系统依然能响应外部中断,中断服务例程依然能进行相应的响应。所以在使用调度器上锁的方式进行任务同步时,需要考虑好任务访问的临界资源是否会被中断服务例程所修改,如果可能会被修改,那么将不适合采用此种方式进行同步。RT-Thread提供的调度锁操作API为:

  调用这个函数后,调度器将被上锁。在锁住调度器期间,系统依然响应中断,如果中断唤醒了更高优先级的线程,调度器并不会立刻执行它,直到调用解锁调度器函数时才会尝试进行下一次调度。、

  当系统退出临界区的时候,系统会计算当前是否有更高优先级的线程就绪,如果有比当前线程更高优先级的线程就绪,将切换到这个高优先级线程中执行;如果无更高优先级线程就绪,将继续执行当前任务。 注: rt_enter_critical/rt_exit_critical可以多次嵌套调用,但每调用一次rt_enter_critical就必须相对应地调用一次rt_exit_critical退出操作,嵌套的最大深度是65535。

  调度器锁能够方便地使用于一些线程与线程间同步的场合,由于轻型,它不会对系统中断响应造成负担;但它的缺陷也很明显,就是它不能被用于中断与线程间的同步或通知,并且如果执行调度器锁的时间过长,会对系统的实时性造成影响(因为使用了调度器锁后,系统将不再具备优先级的关系,直到它脱离了调度器锁的状态)。

  信号量是一种轻型的用于解决线程间同步问题的内核对象,线程可以获取或释放它,从而达到同步或互斥的目的。信号量就像一把钥匙,把一段临界区给锁住,只允许有钥匙的线程进行访问:线程拿到了钥匙,才允许它进入临界区;而离开后把钥匙传递给排队在后面的等待线程,让后续线程依次进入临界区。

  信号量工作示意图如图 信号量工作示意图所示,每个信号量对象都有一个信号量值和一个线程等待队列,信号量的值对应了信号量对象的实例数目、资源数目,假如信号量值为5,则表示共有5个信号量实例(资源)可以被使用,当信号量实例数目为零时,再申请该信号量的线程就会被挂起在该信号量的等待队列上,等待可用的信号量实例(资源)。

  rt_semaphore对象从rt_ipc_object中派生,由IPC容器所管理。信号量的最大值是65535。

  当创建一个信号量时,内核首先创建一个信号量控制块,然后对该控制块进行基本的初始化工作,创建信号量使用下面的函数接口:

  当调用这个函数时,系统将先分配一个semaphore对象,并初始化这个对象,然后初始化IPC对象以及与semaphore相关的部分。在创建信号量指定的参数中,信号量标志参数决定了当信号量不可用时,多个线程等待的排队方式。当选择FIFO方式时,那么等待线程队列将按照先进先出的方式排队,先进入的线程将先获得等待的信号量;当选择PRIO(优先级等待)方式时,等待线程队列将按照优先级进行排队,优先级高的等待线程将先获得等待的信号量。

  RT_IPC_FLAG_FIFO 0x00 /* IPC参数采用FIFO方式*/

  RT_IPC_FLAG_PRIO 0x01 /* IPC参数采用优先级方式*/

  系统不再使用信号量时,可通过删除信号量以释放系统资源。删除信号量使用下面的函数接口:

  rt_err_t rt_sem_delete (rt_sem_t sem);

  调用这个函数时,系统将删除这个信号量。如果删除该信号量时,有线程正在等待该信号量,那么删除操作会先唤醒等待在该信号量上的线程(等待线程的返回值是-RT_ERROR),然后再释放信号量的内存资源。

  脱离信号量就是让信号量对象从内核对象管理器中移除掉。脱离信号量使用下面的函数

  线程通过获取信号量来获得信号量资源实例,当信号量值大于零时,线程将获得信号量,并且相应的信号量值都会减1,获取信号量使用下面的函数接口:

  rt_err_t rt_sem_take (rt_sem_t sem, rt_int32_t

  在调用这个函数时,如果信号量的值等于零,那么说明当前信号量资源实例不可用,申请该信号量的线程将根据time参数的情况选择直接返回、或挂起等待一段时间、或永久等待,直到其他线程或中断释放该信号量。如果在参数time指定的时间内依然得不到信号量,线程将超时返回,返回值是-RT_ETIMEOUT。

  当用户不想在申请的信号量上挂起线程进行等待时,可以使用无等待方式获取信号量,无等待获取信号量使用下面的函数接口:

  这个函数与rt_sem_take(sem, 0) 的作用相同,即当线程申请的信号量资源实例不可用的时候,它不会等待在该信号量上,而是直接返回-RT_ETIMEOUT。

  前言本文学习RT-Thread的消息队列,支持不定长度消息的收发,涉及消息队列的工作机制、消息队列相关函数以及基于STM32的RT-Thread消息队列应用示例,采用RTT正点原子联合出品潘...博文来自:Sanjay_Wu的博客

  在并发问题中,最严重的一类既是死锁。死锁是由于多线程在征用多种资源的时候,所需资源被其他线程独占且无法被抢夺所产生的循环等待的现象。对于java中最常用的synchronized关键字(内置锁),一旦...博文来自:Ghost In Matrix

  同步是指按预定的先后次序进行运行,线程同步是指多个线程通过特定的机制(如互斥量,事件对象,临界区)来控制线程之间的执行顺序,也可以说是在线程之间通过同步建立起执行顺序的关系,如果没有同步,那线程之间将...博文来自:

  大家周末好,刚回学校,乱七八糟的事情一堆,抽个时间更新下~写在前面的话本章主要讲解RTOS的临界段什么是临界段    代码的临界段也称为临界区,指处理时不可分割的代码区域,一旦这部分代码开始执行,则不...博文来自:

  (一)、临界区的保护简单来说,临界区的设立就是为了保护在临界区内的代码不会被外界打断,顺序完整的执行下去,这样做的目的是保证一些共享的资源在执行临界区代码的中途被临界区外的代码改变,造成数据紊乱,功能...博文来自:

  一、什么是中断?中断有两种,一种是CPU本身在执行程序的过程中产生的,一种是由CPU外部产生的。 cpu外部中断,就是通常所讲的“中断”(interrupt)。对于执行程序来说,这种“中断”的发生完全...博文来自:

  rt-thread源码解析今天开发过程遇到一个很奇怪的问题,有一个对喇叭进行声音播放的进程里每次进入这个进程后其他任务都无法工作了,因为这个播放的任务优先级调到了比其他任务都低的级别,本质是为了能在播...博文来自:

  CPU的中断机制是多任务的基础。现代计算机能够有如此的工作效率很大程度依赖于高速多级的中断处理。如果CPU没有中断处理就只能顺序执行代码,想不能时时相应外部处理,无法进行多任务的工作。arm的中断时分...博文来自:

  不论是书上还是网上,对这块的解释,总是很凌乱, 让人不好理清。  大部分开发者可能也只知其然,不知所以然。在网上找到一篇对此解释言简意赅,一看就懂的文章,故分享过来。1、中断中为何不能使用信号量?答:...博文来自:

  临界资源是指一次仅允许一个线程使用的共享资源。不论是硬件临界资源,还是软件临界资源,多个线程必须互斥地对它们进行访问。每个线程中访问临界资源的那段代码称为临界区(CriticalSection),每次...博文来自:

  上面是魔笛开发板上LED和按键的IO分布,我们通过信号量的方法来同步按键线程和LED线程,实现当enter键按下后,点亮或关闭LED的动作。/*****************************...博文来自:

  为什么在单处理器上关闭中断是最简单(直接粗暴)的解决方案?因为,在单处理器的情况下,分时操作系统进行进程调度时依靠的就是中断机制,当CPU进行进程切换时,需要触发特定的中断(其实是trap).所以说,...博文来自:

  调度器上锁函数OSSchedlock()的功能是用于禁止任务调度,使任务保持对CPU的控制权。调度器开锁函数OSSchedUnlock()的功能是解除对任务调度的禁止。 调度器上锁和开锁的实现原理是:...博文来自:

  源代码github网址:,在分支idcard中。 直接贴代码:创建一个文件,内容如下:#include#...博文来自:

  在µC/OS-II中,有多种方法可以保护任务之间的共享数据和提供任务之间的通讯。在前面的章节中,已经讲到了其中的两种:一是利用宏OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL...博文来自:

  原子操作Linux内核提供了多种同步机制,这些机制本质上都是通过原子操作来实现的。原子操作可以保证指令以原子方式执行,不会被中途打断(中断也不会打断一个指令,处理器只有在当前指令完成后才会去处理中断)...博文来自:

  ucosii任务间的同步和通信都可以通过“事件”的方式来搞定,这个事件包括:信号量、互斥量、邮箱和消息队列其中信号量和互斥量用于同步,邮箱和消息队列可用于通信。任务中有任务控制块,同样,在“事件”中有...博文来自:

  用龙芯1c库在RT-Thread下实现外部中断(GPIO中断、按键中断)

  《FreeRTOS多任务之间的通信》(四种信号灯)12-25阅读数 2785

http://4kci.com/tongbutongxinliang/490.html
锟斤拷锟斤拷锟斤拷QQ微锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷微锟斤拷
关于我们|联系我们|版权声明|网站地图|
Copyright © 2002-2019 现金彩票 版权所有