3

Для сближения проблем, которые мы должны синхронизировать две темы, а вот классическое решение:Почему рандеву с решением семафора не обобщают (и вместо этого мы используем барьер)?

aArrived = S(0); 
bArrived = S(0); 

Тема A:

while(true) { 
    doSomething(); 
    aArrived.signal(); 
    bArrived.wait(); 
} 

Тема B:

while(true) { 
    doSomething(); 
    bArrived.signal(); 
    aArrived.wait(); 
} 

Это хорошо работает для два потока, но как насчет N потоков? При N = 3, мы можем реализовать что-то вроде этого:

Thread A (другие потоки симметричны):

while(true) { 
    doSomething(); 
    aArrived.signal(); 
    aArrived.signal(); 
    bArrived.wait(); 
    cArrived.wait(); 
} 

Все источники, которые я нашел только констатировать, что: "Consider again the Rendezvous problem from Section 3.2. A limitation of the solution we presented is that it does not work with more than two threads." или "Solution presented previously doesn't work for more than two threads.".

(Кстати, обобщенное решение, представленное здесь, вероятно, не оптимально, поскольку оно будет использовать N семафоров для N потоков ... Мне просто интересно, есть ли у кого сценарий, что это решение не работает для N> 2 threads?)

+0

Какой язык? Или вы спрашиваете в общем смысле? Причина, по которой я спрашиваю об этом, заключается в том, что в Java есть простой способ сделать это. –

+1

Привет, на самом деле не имеет значения, на каком языке. Есть, вероятно, более простой способ сделать это, но я просто пытаюсь понять, почему обобщение не работает ... Любая идея? :) –

ответ

0

Это было бы очень просто, если вы используете CyclicBarrier на Java, поскольку он делает это для вас. Но для общего случая, как бы вы это сделали и написать сами? Вы можете сделать что-то похожее на то, что делает CountdownLatch или CyclicBarrier.

Ведите подсчет количества ожидаемых сторон, уменьшайте его по мере приближения к своему барьеру и затем сообщайте все, как только декрементированный счет равен 0. Например: (это невероятно упрощено).

class CountdownBarrier { 
    private int numberOfParties; 
    private final Object lock = new Object(); 
    public CountdownBarrier(int numberOfParties){ this.numberOfParties = ..} 

    public void arriveAndAwait(){ 
     synchronized(lock){ 
     if(--numberOfParties == 0) 
      lock.notifyAll(); 
     while(numberOfParties != 0) 
      lock.wait();  
     } 
    } 
} 

Тогда

CountdownBarrier barrier = new CountdownBarrier(3); 

Thread A: 
    barrier.arriveAndAwait(); 
Thread B: 
    barrier.arriveAndAwait(); 
Thread C: 
    barrier.arriveAndAwait(); // assuming time progresses downward, this arriveAndAwait will notify all threads to wake up and continue. 

То же самое можно сделать в Java с помощью

CyclicBarrier#await(); 

или

CountdownLatch#countDown(); // then 
CountdownLatch#await(); 
+1

Привет, Джон, спасибо за ваш ответ! Но мой вопрос заключается в том, чтобы попытаться понять, почему в книгах, таких как «Маленькая книга семафоров», автор говорит, что решение для rendez-vous не работает более чем для двух потоков. Любая идея, почему решение, представленное в моем вопросе, не обобщается? –

 Смежные вопросы

  • Нет связанных вопросов^_^