多任务----同步

实现多任务之间通信的最简便的办法是使用共享的数据结构。虽然共享数据区简化了任务间的通信,但是必须保证 每个任务在处理共享数据时的排他性。以避免竞争和数据破坏。共享资源满足互斥性的一般方法有:
    1.关中断,开中断
    2.使用测试并置位指令
    3.禁止做任务切换
    4.利用信号量
一.关中断&开中断
    这估计是最简单的方法了,代码如下所示。
  1. void function(void)
  2. {
  3.     OS_ENTER_CRITICAL(); //uCOS II中的宏调用,关中断
  4.     /*处理共享数据*/ //读写变量
  5.     OS_EXIT_CRITICAL(); //uCOS II中的宏调用,开中断
  6. }
注意:关中断的时间不能太长,因为它将影响整个系统的中断响应时间(中断延迟时间)。如果仅仅是做为几个变量赋值或者复制几个变量,可以考虑使用这种方法。一般来说:关中断的最长时间不能超过系统本身的关中断时间。
二:测试并置位操作
    即放一个类似于标志位的变量,如果该变量为0,则允许和共享资源交互,而为1则不允许。为防止另一任务也要使用该资源,只需把改标志位置1.注意:这里的标志一般是一条不会被处理器中断的指令。否则应在程序中关中断对该标志位操作,然后再开中断。
这种指令被称作TAS(test and set)指令,在某些处理器中有硬件TAS指令。
三:禁止,然后允许任务切换
    给任务上锁然后开锁 (具体见其它文)
例:
  1. void function(void)
  2. {
  3.     OSSchedlock(); //给任务上锁
  4. /*在这里处理共享数据(中断是开着的)*/
  5.     OSSchedUnlock();//给任务解锁
  6. }
四:信号量
    信号量的本质是一种约定机制。其用于:
    1.控制共享资源的使用权
    2.标志某事件的发生
    3.使两个任务的行为同步
    信号量是任务得以运行的“钥匙”,要运行,必须先拿到“钥匙”。如果信号量被别的任务占用,则该任务挂起,直到信号量被当前的使用者释放。对信号量的操作有三种,初始化(inittialize)或者 建立 (creat);等待信号 (wait)或者挂起 (pend);给信号(signal)或者发信号(post)。信号量初始化时要给信号量赋初值,等待信号的任务列表应清空。
    任务要得到信号量必须:等待(wait),如果信号量有效(大于0),信号量-1任务得以运行。如果信号量为0,任务列入等待信号量任务列表,多数内核支持定义超时。如果等待时间超过了某一个值,该信号量是还无效的,则等待信号量的任务进入就绪状态。准备运行,并返回错误代码(指出发生超时错误)。
    任务以发信号的方式释放信号量,如果没有任务等待信号量。信号量只是简单的加1.如果有任务等待该信号量,信号量的值就不加1.于是“钥匙”给了等待信号量的任务中的一个。至于任务的选择要看内核是如何调度的:
    1.等待信号量的任务中优先级最高的
    2.最早等待信号量的任务(FIFO)uCOS II只支持优先级法。
例:
  1. OS_EVENT *ShareDataSem;
  2. void function(void)
  3. {
  4.     INT8U err;
  5.     OSSemPend(SharedDataSem,0,&err);
  6. /*处理共享数据(中断是开着的)*/
  7.     OSSemPost(ShareDataSem);
  8. }
当多个任务共享输入输出设备时,信号量很有用。 但要注意:信号量不能用过头,处理很简单的数据共享都用信号量,信号量的创建和释放都是要花很多时间的。这种额外的负荷是不必要的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值