2014-03-13 92 views
1

我在使用信号量进行进程同步时遇到了困难。基本上,我没有看到中断会如何破坏程序,并构建场景来解决问题。下面是我坚持了几天的一个问题。请帮忙。提前致谢!关于使用信号量进行线程同步的示例

描述:“H2O”问题。

hReady()和oReady()函数“生成”H和O.每个H线程和O线程执行hReady()和oReady()。准备完成两个H和一个O后,其中一个程序必须调用makewater()。解决方案应避免饥饿和忙碌等待。还假设线程唤醒的FIFO策略。

方法1:这种方法的任何问题? (答案是肯定的,我能理解为什么。)

int numHydrogen = 0; 
sema_t pairOfHydrogen = 0; 
sema_t oxygen = 0; 

void hReady() { 
    numHydrogen ++;    // I'm assuming here should have a mutex 
    if ((numHydrogen % 2) == 0) { 
    signal(pairOfHydrogen); 
    } 
    wait(oxygen); 
} 

void oReady() { 
    wait(pairOfHydrogen); 
    makeWater(); 
    signal(oxygen); 
    signal(oxygen); 
} 

方法2:有什么问题吗? (答案是肯定的,但我不明白为什么还有如何构建一个特定的场景。?)

sema_t hPresent = 0; 
sema_t waitForWater = 0; 

void hReady() { 
    signal(hPresent); 
    wait(waitForWater); 
} 

void oReady() { 
    wait(hPresent);  // It seems something wrong here. I'm not sure why 
    wait(hPresent);  // Also here. Why? 
    makeWater(); 
    signal(waitForWater); 
    signal(waitForWater); 
} 

方法3:在方法2.任何问题假设LIFO线程唤醒窗口? (也是,但是为什么呢?在这个问题中,唤醒策略是如何发挥作用的?)

有没有什么简单的方法可以解决类似的问题?应该怎么考虑构建场景?再次感谢您的帮助!

+0

你有什么问题?另外,你的方法#2是可怕的错误。一个人不应该连续两次等待信号量。这是一个死锁的可爱床。 –

+0

我未能构建场景来描述潜在的问题。特别是在方法2和3中,线程唤醒策略如何影响?在我看来,O线始终可以找到2 H来制造水。 – Yuki

+0

你能否展示更多你的代码?我没有看到你是如何开始线程和在哪里。它们很重要,我感觉到僵局。 –

回答

1

方法1

方案:hReadyoReady之前推出。

hReady线程会发生什么:

  1. 构建一个H
  2. 我们有一对H + - >都能跟得上(都没有信号)
  3. 等待O(阻塞)

oReady线程会发生什么:

  1. 等待H2(没有 - >阻塞)

所以你的2个演员被阻止,因为hReady只产生一个H而不是2,并等待一个永远不会到来的O(因为他也在等待)。 也如您所见,numHydrogen可能需要R/W保护。

方法2

几乎相同的情况下:当您启动hReady你被封锁在waitForWater。 先等待在oReady被解锁,但第二个将永远持续下去,因为你没有信号waitForWater

我不明白approach3虽然...

+0

我可能没有清楚地描述问题......原本可能存在很多O和H.它们每个都可以启动一个线程(oReady( )或hReady())。对运行/阻塞线程的总数没有限制。所以,有可能2个独立的H发起2个线程,并且每个都被单独等待O来阻止...... – Yuki

+1

好吧我不理解它那种抱歉。 对我来说,第一种方法的主要问题是'numHydrogen'没有受到竞争访问的保护。因此2个H线程可能同时计算'numHydrogen%2 == 0'。 如果考虑线程唤醒的FIFO策略,我无法看到第二个错误。然而,在LIFO政策中,如果H的生产速度比O的生产速度快,则第一个阻止的H线程可能永远不会唤醒。 – Coconop

+0

对于延迟,抱歉。你对第二点是对的,我早前在课堂上确定了答案。如果使用FIFO,FIFO队列中阻塞的H-O对总是会在某个点获得另一个H,并形成水。然而,后进先出并非如此。只要到达的订单不是[2 * H和1 * O](可能是H-O-H-O ...或H-O-O -...或者任何不是2H1O),就不会形成水。你的文章非常鼓舞人心,非常感谢! – Yuki