UCOSIII实时操作系统------互斥锁


前言

UCOSIII实时操作系统------互斥锁


提示:以下是本篇文章正文内容,下面案例可供参考

一、概述

互斥锁,亦称:互斥信号量。
在编程中,引入了对象互斥锁的概念,来保证共享数据操作的完整性。每个对象都对应于一个可称为“互斥锁”的标记,这个标记用来保证在任一时刻,只能有一个任务/线程访问该对象(任务之间访问到相同的函数、相同的全局变量)。某个任务得到互斥锁后,就可以访问共享资源,其他任务等待该任务释放互斥锁才能进行访问。
何时可以用普通信号量替代互斥锁?如果没有任务对共享资源访问有截止的时间,那么普通信号量可以替代互斥锁;反之则必须使用互斥锁。因为前者会造成无界优先级反转,后者却不会。

void task(void *parg)
{
	while(1)
	{
		加锁
		访问共享资源
		解锁(立即)

		.....
		加锁
		访问共享资源
		解锁(立即)
		....

	}

}

二、函数接口

1.创建互斥锁

代码如下(示例):

void  OSMutexCreate (OS_MUTEX  *p_mutex,
                     CPU_CHAR  *p_name,
                     OS_ERR    *p_err)

参数
p_mutex,互斥锁对象
p_name,互斥锁名字
p_err,返回错误码,没有错误的就返回OS_ERR_NONE

返回值:无

2.等待互斥锁

若等待成功,则锁定共享资源
代码如下(示例):

void  OSMutexPend (OS_MUTEX  *p_mutex,
                   OS_TICK    timeout,
                   OS_OPT     opt,
                   CPU_TS    *p_ts,
                   OS_ERR    *p_err)

参数
p_mutex,互斥锁对象
timeout,超时时间,默认写0,一直等待
opt,设置当前等待互斥锁的阻塞方式,默认写OS_OPT_PEND_BLOCKING,阻塞等待。如果互斥锁此时被另外一个任务占用,且指定的阻塞类型为OS_OPT_PEND_NON_BLOCKING,则OSMutexPend就会直接返回而不再等待互斥锁被释放。
p_ts,用于记录等待互斥锁花了多长时间,默认写NULL,不记录。
p_err,返回错误码,没有错误的就返回OS_ERR_NONE

说明
如果占有互斥锁是一个较低优先级多任务,那么UCOSIII就会临时提升它的优先级,使得其等于此时想要获取互斥锁的任务优先级。

3.释放互斥锁,解锁

void  OSMutexPost (OS_MUTEX  *p_mutex,
                   OS_OPT     opt,
                   OS_ERR    *p_err)

参数
p_mutex,互斥锁对象
opt,释放互斥锁后希望其他等待锁的任务(最高优先级且就绪)得到立即执行,填写参数OS_OPT_POST_NONE,也是默认值。若使用了OS_OPT_POST_NO_SCHED这个参数,得到互斥锁的任务不会立即执行。
p_err,返回错误码,没有错误的就返回OS_ERR_NONE。

三、死锁(或抱死)

死锁(deadlock)也称做抱死(deadly embrace),指两个任务无限制地互相等待对方控制着的资源。
假设任务T1正独占资源R1,任务T2正独占资源R2,示例代码如下:

void T1(void *parg)
{
	while(1)
	{1)等待事件发生
		
		(2)请求互斥锁M1
		
		(3)访问共享资源R1
		
    		:
    		:4-------   中断!
    		:
    		:8)请求互斥锁M2
		
		(9)访问共享资源R2			
	}
}


void T2(void *parg)
{
	while(1)
	{
		等待事件发生
		
		(5)请求互斥锁M2
		
		(6)访问共享资源R2
		
    		:
    		:7)请求互斥锁M1
		
		访问共享资源R1			
	}
}

(1)假设任务T1具有最高优先级,且其等待的事件发生了,所以任务1开始运行。
(2)任务T1运行并请求获得互斥锁M1
(3)任务T1获得M1并访问共享资源R1
(4)一个中断发生了,导致具有比任务T1更高优先级的T2获得了CPU的使用权。
(5)该中断是任务T2等待的事件,故任务T2继续运行。
(6)任务T2继续运行,请请求获得互斥锁M2以访问共享资源R2。
(7)任务T2想要获得互斥锁M1,但此时UCOSIII知道此时M1被任务T1占用着。
(8)任务T2无法继续运行,UCOSIII做任务切换转而运行任务T1.
(9)任务T1想要获取互斥锁M2,但M2却被任务T2占有了。此时两个任务便死锁了,谁也无法继续运行,因为谁也无法获取对方的资源。

避免出现死锁的方法,让每个任务都:
1)先得到全部需要的资源,再做下一个动作
2)用相同的顺序申请多个资源
3)在调用请求信号量的函数时设定超时时间
以相同的顺序先得到全部需要的资源来避免死锁的问题,示例代码1如下:

void T1(void *parg)
{
	while(1)
	{
		等待事件发生
		
		请求互斥锁M1
		
		请求互斥锁M2	
		
		访问共享资源R1

		访问共享资源R2			
	}
}


void T2(void *parg)
{
	while(1)
	{
		等待事件发生
		
		请求互斥锁M1
		
		请求互斥锁M2	
		
		访问共享资源R1

		访问共享资源R2			
	}
}

以相同的顺序获取资源来避免死锁的问题,示例代码2如下:

void T1(void *parg)
{
	while(1)
	{
		等待事件发生
		
		请求互斥锁M1
		
		访问共享资源R1
		
		请求互斥锁M2	

		访问共享资源R2			
	}
}

void T2(void *parg)
{
	while(1)
	{
		等待事件发生
		
		请求互斥锁M1
		
		访问共享资源R1
		
		请求互斥锁M2	

		访问共享资源R2			
	}
}

总结

以上就是今天要讲的内容,本文仅仅简单介绍了UCOSIII实时操作系统------互斥锁的使用,而UCOSIII实时操作系统还有更多的功能等着我们去挖掘,其他内容请移步博主其他文章或关注博主等待后续发布。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值