搜索
bottom↓
回复: 14

uC/OS-ii中,两个任务之间共享资源,请问如何解决谁先发送信号量呢?

[复制链接]

出0入0汤圆

发表于 2010-12-21 09:26:48 | 显示全部楼层 |阅读模式
(1)、任务1
            void  TaskA (void *pdata)   
           {  
              等待信号量;
              程序实体;  
              发送信号量;  
            }


     (2)、任务2
            void  TaskB (void *pdata)   
           {  
              等待信号量;
              程序实体;  
              发送信号量;  
            }


    多任务运行后,任务A和任务B都请求对方发送信号量,如何解决死锁?(也就是说任务A等待任务B发送信号量,但是任务B又在等待任务A发送信号量,导致死锁)

    解决办法:
              设置等待信号量的TimeOut > 0 , 防止无限等待下去,造成死锁。


   请问:最佳解决办法是什么?

阿莫论坛20周年了!感谢大家的支持与爱护!!

你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。

出0入0汤圆

发表于 2010-12-21 09:46:42 | 显示全部楼层
为什么要采用这种设计呢?

出0入0汤圆

 楼主| 发表于 2010-12-21 10:04:03 | 显示全部楼层
信号量有三种工作方式:
      (1)、任务和任务之间的同步
      (2)、中断和任务之间的同步
      (3)、任务之间共享资源

   我所描述的就是任务之间共享资源。

出0入0汤圆

发表于 2010-12-21 13:40:59 | 显示全部楼层
回复【2楼】ba_wang_mao

   信号量有三种工作方式:
      (1)、任务和任务之间的同步
      (2)、中断和任务之间的同步
      (3)、任务之间共享资源
   我所描述的就是任务之间共享资源。
-----------------------------------------------------------------------

用互斥信号量!
另外,你的这种设计不当!
两个任务用信号量同步应该用以下模式:
(1)、任务1
            void  TaskA (void *pdata)     
           {   
              发送信号量1               
              程序实体;   
              等待信号量2;   
            }  


     (2)、任务2
            void  TaskB (void *pdata)     
           {   
              等待信号量1;  
              程序实体;   
              发送信号量2;   
            }  
这样就不会发生同时等待互相的信号量而死锁!

出0入0汤圆

发表于 2010-12-21 15:43:06 | 显示全部楼层
回复【楼主位】ba_wang_mao
-----------------------------------------------------------------------

如果程序仅仅是你的例子一样简单,那么解决方法也很简单,让semaphore的初值为1就可以了,这里的semaphore就是一个token,用于保护共享资源,在运行时,这个token会在所有访问共享资源的任务之间传递,如果某个时刻,没有任务访问共享资源,这个token就呆在semaphore中。

重要的是,这种方式绝不会出现死锁,因为绝不会出现两个任务都在请求semaphore的情况,如果真出现了,那么这个token到哪里去了?有个任务没有释放而再去请求?

你对死锁的概念还没有搞清,只有单一的共享资源的系统中,不会出现死锁。死锁是指两个或多个任务,它们都在请求对方已经拥有的同步对象(semaphore,mutex等),而造成所有任务都进入阻塞状态。

例如:有两个semaphore:sem1(初值为1),sem2(初值为1)。有两个task:task1,task2。

task1
{
   while (1) {
      ...
      pend(sem1);
      ...
      pend(sem2);   // A
      ...
      post(sem1);
      ...
      post(sem2);
}

task2
{
    while (1) {
      ...
      pend(sem2);   // B
      ...
      pend(sem1);   // C
      ...
      post(sem2);
      ...
      post(sem1);
   }
}

当task1运行到了A点时,已经拥有了sem1,正在请求sem2。如果task2此时正好在B点后(已经拥有了sem2),task1就会进入阻塞。而当task2运行到了C点,请求sem1时,由于sem1已经被task1拥有,因此task2也将被阻塞。这样就形成了死锁。

出0入0汤圆

发表于 2010-12-21 16:06:12 | 显示全部楼层
回复【3楼】AVR_DIY 苹果的另一半
-----------------------------------------------------------------------

你这样做,不仅帮助不了楼主需要解决共享资源的访问的问题。反而使情况更糟。

“任务1”在“发送信号量1”之后直接访问共享资源,而“任务2”在“等待信号量1”之后,也去访问共享资源。

这样根本没有起到保护共享资源的作用。

出0入0汤圆

 楼主| 发表于 2010-12-21 16:40:11 | 显示全部楼层
回复【3楼】AVR_DIY 苹果的另一半
回复【2楼】ba_wang_mao  
   信号量有三种工作方式:  
      (1)、任务和任务之间的同步  
      (2)、中断和任务之间的同步  
      (3)、任务之间共享资源  
   我所描述的就是任务之间共享资源。
-----------------------------------------------------------------------
用互斥信号量!
另外,你的这种设计不当!
两个任务用信号量同步应该用以下模式:
(1)、任务1  
            void  taska (void *pdata)      
           {   
              发送信号量1               
              程序实体;   
              等待信号量2;   
......
-----------------------------------------------------------------------


      你的写法是错误的,以下是周立功的教材:关于信号量资源共享的流程图描述


(原文件名:未命名.JPG)



多任务运行后,任务A和任务B都请求对方发送信号量,如何解决死锁?(也就是说任务A等待任务B发送信号量,但是任务B又在等待任务A发送信号量,导致死锁)

    解决办法:
              设置等待信号量的TimeOut > 0 , 防止无限等待下去,造成死锁。


   请问:最佳解决办法是什么?

出0入0汤圆

发表于 2010-12-21 16:57:15 | 显示全部楼层
很简单。
初始化时赋一个值。就不会,谁也不发而去等。

出0入0汤圆

发表于 2010-12-21 17:11:58 | 显示全部楼层
回复【6楼】John_Lee
回复【3楼】avr_diy 苹果的另一半
-----------------------------------------------------------------------
你这样做,不仅帮助不了楼主需要解决共享资源的访问的问题。反而使情况更糟。
“任务1”在“发送信号量1”之后直接访问共享资源,而“任务2”在“等待信号量1”之后,也去访问共享资源。
这样根本没有起到保护共享资源的作用。

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

是我理解错了,我以为是两个任务之间实现握手同步!学习了!

回复【7楼】ba_wang_mao
回复【3楼】avr_diy 苹果的另一半
回复【2楼】ba_wang_mao   
   信号量有三种工作方式:   
      (1)、任务和任务之间的同步   
      (2)、中断和任务之间的同步   
      (3)、任务之间共享资源   
   我所描述的就是任务之间共享资源。  
-----------------------------------------------------------------------  
用互斥信号量!  
另外,你的这种设计不当!  
两个任务用信号量同步应该用以下模式:  
(1)、任务1   
            void  taska (void *pdata)      
           {     
              发送信号量1                 
              程......
-----------------------------------------------------------------------
5楼不是说的很清楚了吗?你单一资源是不会发生死锁的!不然两个都在等待同一个信号量,那么存在的信号量难道“飞”了???

出0入0汤圆

发表于 2010-12-21 17:28:22 | 显示全部楼层
如果你看过ucos II的源码,你就知道,调用函数OSSemPend等待一个信号量,本质来说,是把调用该函数OSSemPend的任务挂起来。
只要你的程序没有问题,你说的任务1,任务2总有一个会先被执行。

出0入42汤圆

发表于 2010-12-21 17:44:20 | 显示全部楼层
5楼正解

出0入0汤圆

 楼主| 发表于 2010-12-23 11:50:10 | 显示全部楼层
两个任务都要访问全局变量,如何实现资源同步?

  多任务运行后,任务A和任务B都请求对方发送信号量,如何解决:
       任务A等待任务B发送信号量,但是任务B又在等待任务A发送信号量,如何解决谁也不会给对方发送信号量?


  (1)、任务1
            void  TaskA (void *pdata)     
           {   
              等待信号量;  
              程序实体;   
              发送信号量;   
            }  


     (2)、任务2
            void  TaskB (void *pdata)     
           {   
              等待信号量;  
              程序实体;   
              发送信号量;   
            }  


  
   标准答案:

       在创建信号时,初始值必须为“1”。



(原文件名:任务间使用信号量实现资源同步的一般准则.JPG)

出0入0汤圆

发表于 2010-12-23 12:19:47 | 显示全部楼层
实现信号量互斥就是要资源共享,初始化为1那是必须的,不然就“没有资源可抢"

出0入0汤圆

发表于 2012-12-31 12:53:49 | 显示全部楼层
学习  了
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-10-3 01:18

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表