Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.programming > #4127
| From | Kaz Kylheku <kaz@kylheku.com> |
|---|---|
| Newsgroups | comp.programming |
| Subject | Re: randezvous with semaphore have a deadlock |
| Date | 2014-03-04 08:35 +0000 |
| Organization | Aioe.org NNTP Server |
| Message-ID | <20140303232823.685@kylheku.com> (permalink) |
| References | <365a702c-a9ed-41a4-9560-d689c72f990f@googlegroups.com> |
On 2014-03-03, bertanimauro@gmail.com <bertanimauro@gmail.com> wrote:
> Hi, I have a problem with an implementation of a randezvous with the
> semaphore structures.
There is a problem implementing almost anything with semaphores.
Semaphores are the "goto" of process synchronization.
Which is why it is so amusing that they were proposed by Dijkstra, the
staunch proponent of proving programs correct and opponent of goto.
> What I want to do is: The synchronization requirement is that no thread
> executes critical point until after all threads have executed rendezvous. You
> can assume that there are n threads and that this value is stored in a
> variable, n, that is accessible from all threads. When the first n − 1 threads
> arrive they should block until the nth thread arrives, at which point all the
> threads may proceed.
This is also called a "barrier": a synchronization primitive which waits for N
threads to call a single function, "wait".
A useful further refinement in the barrier (an essential feature, I would say)
is that one of these threads returns from the barrier with a special return
value which tells it it is the "serial thread". The serial thread can then
perform some action that only one thread should do.
For instance N threads can "map" some data in parallel in one processing
phase, rendezvous at the barrier, and then the serial
thread can "reduce" the the outputs of the prior parallel computations.
> I try this soltion:
> multiplex = new Semaphore(4) //n = 4
> mutex = new Semaphore(1)
>
> multiplex.wait()
> mutex.wait()
> criticalSection()
> mutex.signal()
> multiplex.signal()
> I have instantiace 10 threads and the program reaches deadlock
> before three threads remains in the multiplex
Although this is not a correct approach to implementing barriers, the threads
should be able to pass through this flow without deadlock. Every wait is
balanced by a signal.
Possibly, you might be using some poorly designed semaphore type which
saturates at (does not increment past) a maximum value, thereby
causing lost wakeups.
You should show your actual source code with the real types that you're using.
The solution you have cannot work because it doesn't exhibit the behavior of
blocking n - 1 threads, and then releasing the whole herd when thread n
arrives. Semaphores do not do this "out of the box"; you have to
orchestrate the semaphores into a clever "mouse trap".
One idea is to implement the barrier with a "barrier manager" thread. The
barrier wait operation posts a request to the manager's receive queue and
blocks, waiting for a reply. The manager monitors the queue, and counts the
requests. When it collects ten requests, then it replies to all of the
messages.
Here is a simpler idea:
n_waiting = 0
mutex = Semaphore(0)
barrier = Semaphore(0)
wait_op:
mutex.wait() // acquire lock
if (++n_waiting == n) // am I thread n?
n_waiting = 0
repeat n-1 // yes: wake the other n-1
barrier.signal()
mutex.signal() // give up lock
return true // report: "I am the serial thread"
else // I am not thread #n
mutex.signal() // give up lock
barrier.wait() // wait for thread #n to signal me
return false // report: "I am not the serial thread"
We keep the lock over the barrier.signal() operation, because as soon as we
kick the barrier semaphore, the threads will want to spin around and call
wait_op again. That will interfere with the count.
We can actually allow them to do that, by doing it like this.
This should still work:
n_waiting = 0
mutex = Semaphore(0)
barrier = Semaphore(0)
wait_op:
I_am_serial = false
mutex.wait()
if (n_waiting == n - 1)
n_waiting = 0
i_am_serial = true
else
n_waiting++
mutex.signal()
if (I_am_serial)
repeat n - 1
barrier.signal()
else
barrier.wait()
return I_am_serial
Back to comp.programming | Previous | Next — Previous in thread | Find similar | Unroll thread
randezvous with semaphore have a deadlock bertanimauro@gmail.com - 2014-03-03 07:07 -0800 Re: randezvous with semaphore have a deadlock Kaz Kylheku <kaz@kylheku.com> - 2014-03-04 08:35 +0000
csiph-web