uC/OS-ii中,两个任务之间共享资源,请问如何解决谁先发送信号量呢?
(1)、任务1voidTaskA (void *pdata)
{
等待信号量;
程序实体;
发送信号量;
}
(2)、任务2
voidTaskB (void *pdata)
{
等待信号量;
程序实体;
发送信号量;
}
多任务运行后,任务A和任务B都请求对方发送信号量,如何解决死锁?(也就是说任务A等待任务B发送信号量,但是任务B又在等待任务A发送信号量,导致死锁)
解决办法:
设置等待信号量的TimeOut > 0 , 防止无限等待下去,造成死锁。
请问:最佳解决办法是什么? 为什么要采用这种设计呢? 信号量有三种工作方式:
(1)、任务和任务之间的同步
(2)、中断和任务之间的同步
(3)、任务之间共享资源
我所描述的就是任务之间共享资源。 回复【2楼】ba_wang_mao
信号量有三种工作方式:
(1)、任务和任务之间的同步
(2)、中断和任务之间的同步
(3)、任务之间共享资源
我所描述的就是任务之间共享资源。
-----------------------------------------------------------------------
用互斥信号量!
另外,你的这种设计不当!
两个任务用信号量同步应该用以下模式:
(1)、任务1
voidTaskA (void *pdata)
{
发送信号量1
程序实体;
等待信号量2;
}
(2)、任务2
voidTaskB (void *pdata)
{
等待信号量1;
程序实体;
发送信号量2;
}
这样就不会发生同时等待互相的信号量而死锁! 回复【楼主位】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也将被阻塞。这样就形成了死锁。 回复【3楼】AVR_DIY 苹果的另一半
-----------------------------------------------------------------------
你这样做,不仅帮助不了楼主需要解决共享资源的访问的问题。反而使情况更糟。
“任务1”在“发送信号量1”之后直接访问共享资源,而“任务2”在“等待信号量1”之后,也去访问共享资源。
这样根本没有起到保护共享资源的作用。 回复【3楼】AVR_DIY 苹果的另一半
回复【2楼】ba_wang_mao
信号量有三种工作方式:
(1)、任务和任务之间的同步
(2)、中断和任务之间的同步
(3)、任务之间共享资源
我所描述的就是任务之间共享资源。
-----------------------------------------------------------------------
用互斥信号量!
另外,你的这种设计不当!
两个任务用信号量同步应该用以下模式:
(1)、任务1
voidtaska (void *pdata)
{
发送信号量1
程序实体;
等待信号量2;
......
-----------------------------------------------------------------------
你的写法是错误的,以下是周立功的教材:关于信号量资源共享的流程图描述
http://cache.amobbs.com/bbs_upload782111/files_35/ourdev_606121NJ4HLY.JPG
(原文件名:未命名.JPG)
多任务运行后,任务A和任务B都请求对方发送信号量,如何解决死锁?(也就是说任务A等待任务B发送信号量,但是任务B又在等待任务A发送信号量,导致死锁)
解决办法:
设置等待信号量的TimeOut > 0 , 防止无限等待下去,造成死锁。
请问:最佳解决办法是什么? 很简单。
初始化时赋一个值。就不会,谁也不发而去等。 回复【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
voidtaska (void *pdata)
{
发送信号量1
程......
-----------------------------------------------------------------------
5楼不是说的很清楚了吗?你单一资源是不会发生死锁的!不然两个都在等待同一个信号量,那么存在的信号量难道“飞”了??? 如果你看过ucos II的源码,你就知道,调用函数OSSemPend等待一个信号量,本质来说,是把调用该函数OSSemPend的任务挂起来。
只要你的程序没有问题,你说的任务1,任务2总有一个会先被执行。 5楼正解 两个任务都要访问全局变量,如何实现资源同步?
多任务运行后,任务A和任务B都请求对方发送信号量,如何解决:
任务A等待任务B发送信号量,但是任务B又在等待任务A发送信号量,如何解决谁也不会给对方发送信号量?
(1)、任务1
voidTaskA (void *pdata)
{
等待信号量;
程序实体;
发送信号量;
}
(2)、任务2
voidTaskB (void *pdata)
{
等待信号量;
程序实体;
发送信号量;
}
标准答案:
在创建信号时,初始值必须为“1”。
http://cache.amobbs.com/bbs_upload782111/files_35/ourdev_606581P56XSS.JPG
(原文件名:任务间使用信号量实现资源同步的一般准则.JPG) 实现信号量互斥就是要资源共享,初始化为1那是必须的,不然就“没有资源可抢" 学习了
页:
[1]