信号量笔记

 1、信号量简介

信号量是一种实现任务间通信机制,可以实现任务之间同步临界资源的互斥访问,常用于协助一组相互竞争的任务来访问临界资源。在多任务系统中,各任务之间需要同步或互斥实现临界资源的访问,信号量功能可以为用户提供这方面的支持。

抽象的来讲,信号量是一个非负整数,所有获取它的任务都会将该整数减一,当该整数值为零时,所有试图获取它的任务都将处于阻塞状态。通常一个信号量的计数值用于对应有效的资源数,表示剩下的可被占用的互斥资源数。

信号量的计数值都有限制:限定最大值。

如果最大值被限定为1,那么它就是二值信号量

如果最大值不是1,它就是计数型信号量

---------------------------------------------------------------------------------------------------------------------------------队列与信号量的对比

---------------------------------------------------------------------------------------------------------------------------------

2、二值信号量

简介

二值信号量的本质是一个队列长度为1的队列,该队列只有空和满两种情况,这就是所谓的二值。

二值信号量通常用于互斥访问或任务同步,与互斥信号量比较类似,但是二值信号量有可能会导致优先级翻转的问题,所以二值信号量更适合用于同步

什么是同步啊?举个例子吧。

用作同步时,信号量在创建后应被置为空,任务1获取信号量而进入阻塞状态,任务2在某种条件发生后,任务2运行并在最后释放信号量,于是任务1获得信号量得以进入就绪态,如果任务1的优先级是最高的,那么就会立即切换任务,任务1执行完成后并不需要归还信号量,从而达到了两个任务间的同步。同样的,在中断服务函数中释放信号量,任务1也会得到信号量,从而达到任务与中断间的同步。

---------------------------------------------------------------------------------------------------------------------------------

这里有一个知识点,优先级翻转

顾名思义,优先级翻转的意思就是高优先级的任务反而慢执行,而低优先级的任务反而优先执行。

优先级翻转在抢占式内核中是非常常见的,但是在实时操作系统中是不允许出现优先级翻转的,因为优先级翻转会破坏任务的预期顺序,可能会导致未知的严重后果。

这么纯说还是有一些抽象,那我要拿出正点原子的例子并解释一通了。

前提条件:任务L的优先级最低,M的优先级中,H的优先级最高;任务L和H的开头和结尾需要获取信号量然后释放信号量,任务M不需要。

L先执行,然后H想要执行,但是信号量的计数值此时为0,H没有办法执行而进入阻塞状态,所以L继续执行,然后M执行,因为M不需要信号量,所以M执行,等M和L都执行完,H才能执行,这个时候就会出现M优先级比H低,但是M先于H执行。

高优先级任务被低优先级任务阻塞,导致高优先级任务迟迟得不到调度。但其他中等优先级的任务却能抢到CPU资源。从现象上看,就像是中优先级的任务比高优先级任务具有更高的优先权(即优先级翻转)

---------------------------------------------------------------------------------------------------------------------------------

上一张信号量的图吧。

相关API函数

使用二值信号量的流程与队列类似,使用二值信号量的流程为:创建二值信号量、释放二值信号量、获取二值信号量。

后边的计数信号量和互斥信号量的释放和获取与这里使用的函数一致。

动态方式创建二值信号量

 #define   xSemaphoreCreateBinary( )   						
 xQueueGenericCreate( 1 ,   semSEMAPHORE_QUEUE_ITEM_LENGTH  ,   queueQUEUE_TYPE_BINARY_SEMAPHORE )
#define  semSEMAPHORE_QUEUE_ITEM_LENGTH      ( ( uint8_t ) 0U )

使用该函数创建的二值信号量是空的。

返回值

释放二值信号量函数

获取二值信号量函数

信号量删除函数

vSemaphoreDelete()用于删除一个信号量,包括二值信号量、计数信号量和互斥信号量。如果有任务阻塞在该信号量上,那么不要删除该信号量。

函数原型:

void vSemaphoreDelete(SemaphoreHandle_t xSemaphore);

传入参数:

信号量句柄。

3、计数型信号量

简介

计数型信号量相当于队列长度大于1的队列,因此计数型信号量能够容纳多个资源,这在计数型信号量被创建的时候确定。

计数型信号量使用场合

事件计数:当每次事件发生后,在事件处理函数中释放计数型信号量(计数值+1),其他任务会获取计数型信号量(计数值-1),这种场合一般在创建时将初始计数值设置为0。

资源管理:信号量表示有效的资源数目。任务必须先获取信号量(信号量计数值-1)才能获取资源控制权。当计数值减为零时表示没有资源。当任务使用完资源后,必须释放信号量(信号量计数值+1)。信号量创建时计数值应等于最大资源数目。

相关API函数

动态方式创建计数型信号量

获取信号量的计数值函数

4、互斥信号量

简介

互斥信号量其实就是一个拥有优先级继承的二值信号量,互斥信号量适合用于那些需要互斥访问的应用中。

用作互斥时,信号量创建后可用信号量个数应该是满的,任务在需要使用临界资源时(临界资源是指任何时刻只能被一个任务访问的资源),先获取互斥信号量,使其变空,这样其他任务需要使用临界资源时就会因为无法获取信号量而进入阻塞,从而保证了临界资源的安全。

在操作系统中,我们使用信号量的很多时候是为了给临界资源建立一个标志,信号量表示了该临界资源被占用情况。这样,当一个任务在访问临界资源的时候,就会先对这个资源信息进行查询,从而在了解资源被占用的情况之后,再做处理,从而使得临界资源得到有效的保护。

---------------------------------------------------------------------------------------------------------------------------------

优先级继承:当一个互斥信号量正在被一个低优先级的任务持有时,如果此时有个高优先级的任务也尝试获取这个互斥信号量,那么这个高优先级的任务就会被阻塞。不过这个高优先级的任务会将低优先级任务的优先级提升到与自己相同的优先级。

优先级继承并不能完全消除优先级翻转的问题,它只能尽可能的降低优先级翻转带来的影响。

H把L的优先级提升到与自己相同,那么M就不能抢占L。

---------------------------------------------------------------------------------------------------------------------------------

互斥信号量不能用于中断服务函数中,原因如下:

(1)互斥信号量有任务优先级继承的机制,但是中断不是任务,没有任务优先级,所以互斥信号量只能用于任务中,不能用于中断服务函数。

(2)中断服务函数中不能因为要等待互斥信号量而设置阻塞时间进入阻塞态。

相关API函数

互斥信号量创建API函数(动态)

注意:创建互斥信号量时,会主动释放一次信号量。

  • 8
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RT-Thread是一个实时操作系统,它提供了信号量机制来实现线程之间的同步和互斥。信号量是一种计数器,用于控制对共享资源的访问。在RT-Thread中,有几种方式可以获取信号量。 一种方式是在信号量无效的情况下获取信号量,此时如果有线程尝试获取该信号量,线程将进入阻塞状态,直到信号量变为有效。这种方式可以使用rt_sem_take函数来实现。\[1\] 另一种方式是无等待获取信号量,当线程不想在申请的信号量上挂起等待时,可以使用无等待方式获取信号量。这种方式使用rt_sem_trytake函数,如果线程申请的信号量资源实例不可用,函数将直接返回RT_ETIMEOUT。\[2\] 当中断或线程释放了信号量时,由于获取无效信号量而进入阻塞态的线程将获得信号量并恢复为就绪态。这种情况可以通过中断或线程释放信号量来实现。\[3\] 总之,RT-Thread提供了多种方式来获取信号量,以实现线程之间的同步和互斥。 #### 引用[.reference_title] - *1* *2* *3* [RT-Thread学习笔记——信号量](https://blog.csdn.net/Sanjay_Wu/article/details/86645741)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值