信号量:增强型游泳池
Semaphores : enhanced swimming pool
我在做进程同步,游泳池问题的改进版:
Bathers want to go to the swimming pool:
- They have to take an empty basket
- They have to go in a free cubicle
- They put their swimsuit on, put their clothes in the basket and leave the cubicle
- They swim
- They head back to a free cubicle with their basket
- They put their clothes back on, and leave the cubicle
- They give the empty basket back
- There is a limited number of baskets and cubicles
- If a bather can't find an empty basket or a free cubicle, he will wait until one is available
IMPROVED VERSION:
- There are members and non-members
- The members have priority over non-members
- If one resource becomes available, it will be given to a waiting member, and if there's not, it will be given to anyone waiting.
为此,我想我会使用 3 个信号量:一个用于篮子,一个用于隔间,一个用于等待的成员。这样,当会员等待时,信号量将阻止任何调用 P(s_members)
的进程,而当会员最终获得篮子时,他会调用 V(s_members)
。但是可以有几个成员在队列中等待,信号量不应该在每次V(s_members)
被调用时'release'一个非成员。这就是为什么我认为 sembuf.sem_op = 0;
会很划算,因为非会员必须等待 0.
问题是这个解决方案:
- 非会员在致电
P(s_basket)
或P(s_cubicle)
前必须先致电P(s_members)
。
- 非会员必须调用
P(s_members)
才能入睡并与其他人一起排队,但他们不需要increase/decrease信号量的值,因为它不依赖于他们。
- 等待资源的成员需要调用
P(s_members)
才能increase/decrease它的值(因为他们在队列中),但他们不需要睡着继续等待他们的篮子。
- 想象一下这种情况:一个非会员正在等待他的篮子,此时队列中没有会员。然后,一个成员出现了,显然,他也在等待资源。此时,也在等待的非会员也应该睡着,直到会员离开队列,但他们已经在等待他们的篮子时睡着了,这意味着他们已经打电话给
P(s_members)
。因此,优先规则不适用。
我们如何解决这个问题?
我希望它足够清楚,很难解释而且很容易把它搞砸。
感谢您花时间阅读本文。
编辑:
抱歉,如果我将此发布到错误的 StackExchange 社区,下次我会三思而后行!
imagine this case: a non-member is waiting for his basket, and there
are no members in the queue at the moment. Then, a member shows up,
and obviously, he is waiting for resources too. At this point, the
non-members who were waiting too should fall asleep until the member
leaves the queue, but they are already asleep waiting for their
basket, which means they already called P(s_members). As a result, the
priority rule does not apply.
所以你说的是 "if a non-member goes to sleep in the same queue as members do, we're screwed"。我同意。一旦非成员在队列中进入休眠状态,您以后就无法完全将他们拉出来。
由于非成员和成员不能在同一个信号量上等待资源,s_basket
一定是错误的。
试试 s_basket_members
和 s_basket_nonmembers
怎么样?
我相信您还需要跟踪一些 int
,例如有多少 members/non-members 正在等待,以及有多少篮子可用。
我在做进程同步,游泳池问题的改进版:
Bathers want to go to the swimming pool:
- They have to take an empty basket
- They have to go in a free cubicle
- They put their swimsuit on, put their clothes in the basket and leave the cubicle
- They swim
- They head back to a free cubicle with their basket
- They put their clothes back on, and leave the cubicle
- They give the empty basket back
- There is a limited number of baskets and cubicles
- If a bather can't find an empty basket or a free cubicle, he will wait until one is available
IMPROVED VERSION:
- There are members and non-members
- The members have priority over non-members
- If one resource becomes available, it will be given to a waiting member, and if there's not, it will be given to anyone waiting.
为此,我想我会使用 3 个信号量:一个用于篮子,一个用于隔间,一个用于等待的成员。这样,当会员等待时,信号量将阻止任何调用 P(s_members)
的进程,而当会员最终获得篮子时,他会调用 V(s_members)
。但是可以有几个成员在队列中等待,信号量不应该在每次V(s_members)
被调用时'release'一个非成员。这就是为什么我认为 sembuf.sem_op = 0;
会很划算,因为非会员必须等待 0.
问题是这个解决方案:
- 非会员在致电
P(s_basket)
或P(s_cubicle)
前必须先致电P(s_members)
。 - 非会员必须调用
P(s_members)
才能入睡并与其他人一起排队,但他们不需要increase/decrease信号量的值,因为它不依赖于他们。 - 等待资源的成员需要调用
P(s_members)
才能increase/decrease它的值(因为他们在队列中),但他们不需要睡着继续等待他们的篮子。 - 想象一下这种情况:一个非会员正在等待他的篮子,此时队列中没有会员。然后,一个成员出现了,显然,他也在等待资源。此时,也在等待的非会员也应该睡着,直到会员离开队列,但他们已经在等待他们的篮子时睡着了,这意味着他们已经打电话给
P(s_members)
。因此,优先规则不适用。
我们如何解决这个问题?
我希望它足够清楚,很难解释而且很容易把它搞砸。
感谢您花时间阅读本文。
编辑:
抱歉,如果我将此发布到错误的 StackExchange 社区,下次我会三思而后行!
imagine this case: a non-member is waiting for his basket, and there are no members in the queue at the moment. Then, a member shows up, and obviously, he is waiting for resources too. At this point, the non-members who were waiting too should fall asleep until the member leaves the queue, but they are already asleep waiting for their basket, which means they already called P(s_members). As a result, the priority rule does not apply.
所以你说的是 "if a non-member goes to sleep in the same queue as members do, we're screwed"。我同意。一旦非成员在队列中进入休眠状态,您以后就无法完全将他们拉出来。
由于非成员和成员不能在同一个信号量上等待资源,s_basket
一定是错误的。
试试 s_basket_members
和 s_basket_nonmembers
怎么样?
我相信您还需要跟踪一些 int
,例如有多少 members/non-members 正在等待,以及有多少篮子可用。