Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Understanding pthread_cond_wait()

14 views
Skip to first unread message

lance...@yahoo.com

unread,
Sep 26, 2008, 10:28:05 PM9/26/08
to
Hi all,

I would like to know if my understanding on how the program handles
pthread_cond_wait() and pthread_cond_signal() is correct.

Given the code below,

// Thread A
while (1)
{
do_Awork();
signal = 1;
pthread_cond_signal(&condition);
signal = 0;
}

// Thread B, C, D
while (1)
{
pthread_mutex_lock(&mutex);
while (!signal)
pthread_cond_wait(&condition, &mutex);
do_BCDwork();
pthread_mutex_unlock(&mutex);
}

"mutex" and"condition" are global variables that have been
initialized. "signal" is also a global variable that has been
initialized to 0. The program should only execute do_BCDwork() in
Thread B, C and D when Thread A finishes do_Awork() and changes signal
to 1. Then Thread A signals either Thread B, C or D, sets signal to 0
again and repeat the whole process.

I would like to understand the flow and logic of the above code, and
please tell me if I misunderstood anything.

I'll start with say, Thread B that enters the while(1) loop, locks
mutex and enters the while (!signal) loop, which is true and so it
calls pthread_cond_wait(), at the same time unlocking the mutex. Now
Thread C goes into the while(1) loop, locks the mutex, enters the
while (!signal) loop, which is true and it calls pthread_cond_wait(),
at the same time unlocking the mutex. Sane thing happens to Thread D.
So we now have all three threads waiting at pthread_cond_wait().

Say, at this point Thread A enters its while(1) thread, runs
do_Awork(), then sets signal = 1. It then calls pthread_cond_signal()
and say, Thread C gets woken up. (Any of the three threads can get
signaled, right? It need not be in the order they called
pthread_cond_wait()?)

Thread C, after waking up, returns from pthread_cond_wait() and checks
the while(!signal) loop, which is now false and so it goes out of that
while loop, locks the mutex and runs do_BCDwork(). Thread A sets
signal back to 0. (One question, could Thread A set signal = 0 faster
than Thread C checking the while(!signal) loop, hence, resulting in
Thread C calling pthread_cond_wait() again since the while-loop
condition is not met? If so, should I put a usleep(100) before signal
= 0 so that this won't happen?)

After running do_BCDwork(), Thread C unlocks the mutex. Then it locks
the mutex again since it has to stay in the while(1) loop, checks that
while(!signal) is true and calls pthread_cond_wait(). This process
repeats itself, only either Thread, B, C or D can be woken up each
time Thread A sets signal = 1.

Is my understanding of the logic correct? What other things should I
look out for?

Also, this shouldn't be a one-to-one "relationship", that is, Thread A
wakes up one thread, that thread finishes do_BCDwork(), goes into
pthread_cond_wait(), then Thread A wakes up another thread, that
thread finishes do_BCDwork(), goes into pthread_cond_wait(), and so
on. The program should have Thread A wake up one thread, that thread
finishes do_BCDwork(), and while that is happening, another thread can
be woken up by Thread A and it carries out do_BCDwork() too. (The
variables in do_BCDwork() are kept different so different threads can
carry out do_BCDwork() independently and not interfere/change anything
the other threads are working on.) However, I realize that if this
were to happen, say Thread C gets woken up first, it would lock the
mutex wile it does do_BCDwork(). If Thread B were also to get woken up
at this time, it would also try to lock the mutex that Thread C is
holding, in order to execute do_BCDwork(), which would give me an
error (This might be why I keep getting "Segmentation fault" in my
program). Is there some way to workaround this?

Thank you.

Regards,
Rayne

Chris M. Thomasson

unread,
Sep 27, 2008, 12:19:14 AM9/27/08
to

<lance...@yahoo.com> wrote in message
news:a099c363-65be-4a41...@a29g2000pra.googlegroups.com...

> Hi all,
>
> I would like to know if my understanding on how the program handles
> pthread_cond_wait() and pthread_cond_signal() is correct.
>
> Given the code below,
>
> // Thread A
> while (1)
> {
> do_Awork();
> signal = 1;
> pthread_cond_signal(&condition);
> signal = 0;
> }
>
> // Thread B, C, D
> while (1)
> {
> pthread_mutex_lock(&mutex);
> while (!signal)
> pthread_cond_wait(&condition, &mutex);
> do_BCDwork();
> pthread_mutex_unlock(&mutex);
> }
[...]


// Thread A
for (;;) {
pthread_mutex_lock(&mutex);
do_Awork();
signal = 1;
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&condition);
}


// Threads B, C, D
for (;;) {
pthread_mutex_lock(&mutex);
while (! signal) {
pthread_cond_wait(&condition, &mutex);
}
do_BCDwork();
signal = 0;
pthread_mutex_unlock(&mutex);
}

lance...@yahoo.com

unread,
Sep 27, 2008, 7:30:53 AM9/27/08
to
On Sep 27, 12:19 pm, "Chris M. Thomasson" <n...@spam.invalid> wrote:
> <lancer6...@yahoo.com> wrote in message
>
> news:a099c363-65be-4a41...@a29g2000pra.googlegroups.com...
>
>

> [...]
>
> // Thread A
> for (;;) {
>   pthread_mutex_lock(&mutex);
>   do_Awork();
>   signal = 1;
>   pthread_mutex_unlock(&mutex);
>   pthread_cond_signal(&condition);
>
> }
>
> // Threads B, C, D
> for (;;) {
>   pthread_mutex_lock(&mutex);
>   while (! signal) {
>     pthread_cond_wait(&condition, &mutex);
>   }
>   do_BCDwork();
>   signal = 0;
>   pthread_mutex_unlock(&mutex);
>
> }

This was what I initially did, but both do_Awork() and do_BCDwork()
access a global queue (array of pointers) and by putting a mutex
around the queue, it means that at any one time, only one thread can
access the queue, and it slows down my program, so I was thinking if
there was a way to have several threads simultaneously access
different parts of the queue (via do_Awork() and do_BCDwork()).

Markus Elfring

unread,
Sep 28, 2008, 2:50:09 AM9/28/08
to
> This was what I initially did, but both do_Awork() and do_BCDwork()
> access a global queue (array of pointers) and by putting a mutex
> around the queue, it means that at any one time, only one thread can
> access the queue, and it slows down my program, so I was thinking if
> there was a way to have several threads simultaneously access
> different parts of the queue (via do_Awork() and do_BCDwork()).

Do you distinguish between shared access for each element and concurrent queue
operations?
Will you need to tweak your synchronisation implementation a bit more?

Regards,
Markus

Szabolcs Ferenczi

unread,
Sep 28, 2008, 7:26:13 AM9/28/08
to
On Sep 27, 4:28 am, "lancer6...@yahoo.com" <lancer6...@yahoo.com>
wrote:

> Hi all,
>
> I would like to know if my understanding on how the program handles
> pthread_cond_wait() and pthread_cond_signal() is correct.
>
> Given the code below,
>
> // Thread A
> while (1)
> {
> do_Awork();
> signal = 1;
> pthread_cond_signal(&condition);
> signal = 0;
>
> }
>
> // Thread B, C, D
> while (1)
> {
> pthread_mutex_lock(&mutex);
> while (!signal)
> pthread_cond_wait(&condition, &mutex);
> do_BCDwork();
> pthread_mutex_unlock(&mutex);
>
> }

When you consider using condition variables, it always helps you if
you know about the condition variable test:
http://groups.google.com/group/comp.programming.threads/browse_frm/thread/0ff7ac10adadee22

You can fix your algorithm in two different ways:

1) Fix the implementation of the problem-level event signalling based
on the shared flags, mutex and condition variable.

2) Use a semaphore for the problem-level event signalling.

See the proposed solutions at the end.

> [...]


> I would like to understand the flow and logic of the above code, and
> please tell me if I misunderstood anything.

See notes below.

> [...]


> Say, at this point Thread A enters its while(1) thread, runs
> do_Awork(), then sets signal = 1. It then calls pthread_cond_signal()
> and say, Thread C gets woken up.

That is a typical misuse of the condition variable. You can use the
condition variable in an auxiliary manner, i.e. for optimisation for
the problem-level busy waiting loop. That means you do not call signal
on a condition variable to send a problem level signal. You can use
semaphores that way but not the condition variable. You can call
signal on a condition variable only to notify the waiting threads that
there is some change in the shared data space. (The shared data space
is in your case the shared flag `signal'.)

> (Any of the three threads can get
> signaled, right? It need not be in the order they called
> pthread_cond_wait()?)

Yes, a signal can wake up any of the threads which is waiting on that
condition variable at the time a signal is made.

> [...] (One question, could Thread A set signal = 0 faster


> than Thread C checking the while(!signal) loop, hence, resulting in
> Thread C calling pthread_cond_wait() again since the while-loop
> condition is not met? If so, should I put a usleep(100) before signal
> = 0 so that this won't happen?)

You MUST NOT use any sleep operation to fix a scheduling problem. You
do not solve the scheduling problem with sleeps rather you only
postpone the problem. The correct way is to arrange for
synchronisation among threads. In your case the flag could be re-set
on the side the request is accepted. But even that does not solve all
your synchronisation problems since you may lost requests if thread A
sets the flag again while it is already set. (See solution proposals
below.)

> [...]


> Is my understanding of the logic correct? What other things should I
> look out for?

The other thing you should always consider is that you cannot assume
anything about the relative speed of the threads. For instance, in
your case, if the speed of threads B-D is significantly slower than
the speed of thread A, thread A may send several problem-level signals
while the others are busy carrying on the previous requests.

> Also, this shouldn't be a one-to-one "relationship", that is, Thread A
> wakes up one thread, that thread finishes do_BCDwork(), goes into
> pthread_cond_wait(), then Thread A wakes up another thread, that
> thread finishes do_BCDwork(), goes into pthread_cond_wait(), and so
> on. The program should have Thread A wake up one thread, that thread
> finishes do_BCDwork(), and while that is happening, another thread can
> be woken up by Thread A and it carries out do_BCDwork() too.

If the threads carry out action do_BCDwork() with mutual exclusion,
this will not happen.

> (The
> variables in do_BCDwork() are kept different so different threads can
> carry out do_BCDwork() independently and not interfere/change anything
> the other threads are working on.)

Then, if this is the case, you do not have to provide mutual exclusion
between threads B, C or D so move it outside the Critical Region. But
that also means you end up with a simpler solution if you use
semaphore for problem-level event signalling (see below).

> However, I realize that if this
> were to happen, say Thread C gets woken up first, it would lock the
> mutex wile it does do_BCDwork(). If Thread B were also to get woken up
> at this time, it would also try to lock the mutex that Thread C is
> holding, in order to execute do_BCDwork(), which would give me an
> error (This might be why I keep getting "Segmentation fault" in my
> program). Is there some way to workaround this?

Yes, there is.

Now it looks like you do not need any mutual exclusion between the
threads B, C or D and you want to communicate a problem-level signal
from thread A to threads B, C or D. You can solve it with a semaphore:

sem_t signal;
...
enum {THREAD_LOCAL = 0, CLOSED = 0}
sem_init(&signal, THREAD_LOCAL, CLOSED);
...


// Thread A
while (1)
{
do_Awork();

sem_post(&signal);
}

// Thread B, C, D
while (1)
{

sem_wait(&signal);
do_BCDwork();
}

This solution still implies that actions do_Awork() and do_BCDwork()
can be carried out simultaneously. Note that the Pthread semaphore is
a counting semaphore, so it keeps track of how many posted signal it
has.

If you want to solve it with condition variable for some strange
reason, here is the fixed version:

// Thread A
while (1)
{
do_Awork();

pthread_mutex_lock(&mutex);
signal++;
pthread_cond_signal(&condition);
pthread_mutex_unlock(&mutex);
}

// Thread B, C, D
while (1)
{
pthread_mutex_lock(&mutex);

while (signal == 0)
pthread_cond_wait(&condition, &mutex);
signal--;
pthread_mutex_unlock(&mutex);
do_BCDwork();
}

Note that you should use a shared integer counter instead of the
shared boolean flag if you do not want to loose problem-level signals.

Which solution seems to be simpler to you? Is the semaphore-based one
or the condition variable-based one simpler for communicating a
problem-level event?

Best Regards,
Szabolcs

Chris M. Thomasson

unread,
Sep 28, 2008, 4:44:24 PM9/28/08
to

"Szabolcs Ferenczi" <szabolcs...@gmail.com> wrote in message
news:e2f3e0ea-83c8-477e...@8g2000hse.googlegroups.com...

> On Sep 27, 4:28 am, "lancer6...@yahoo.com" <lancer6...@yahoo.com>
> wrote:
[...]

> // Thread A
> while (1)
> {
> do_Awork();
> sem_post(&signal);
> }
>
> // Thread B, C, D
> while (1)
> {
> sem_wait(&signal);
> do_BCDwork();
> }
[...]

That's potentially broken because `sem_wait()' can return without a post to
the semaphore; it can return when internal sem value is 0; think along the
lines of `EINTR'. The fix for the pseudo-code is fairly simple:


for (;;) {
while (sem_wait(&signal) == EINTR);
do_BCDwork();
}

Szabolcs Ferenczi

unread,
Sep 28, 2008, 4:56:49 PM9/28/08
to
On Sep 28, 10:44 pm, "Chris M. Thomasson" <n...@spam.invalid> wrote:
> "Szabolcs Ferenczi" <szabolcs.feren...@gmail.com> wrote in message

>
> news:e2f3e0ea-83c8-477e...@8g2000hse.googlegroups.com...
>
> > On Sep 27, 4:28 am, "lancer6...@yahoo.com" <lancer6...@yahoo.com>
> > wrote:
> [...]
> > // Thread A
> > while (1)
> > {
> >   do_Awork();
> >   sem_post(&signal);
> > }
>
> > // Thread B, C, D
> > while (1)
> > {
> >   sem_wait(&signal);
> >   do_BCDwork();
> > }
>

Hmmm... Do we have a second forum monkey next to DS? Do you feel you
have to jump?

> [...]
>
> That's potentially broken ...

Still, it is much better than your factually broken attempt here:
http://groups.google.com/group/comp.programming.threads/msg/233368e9feb5db93

> because `sem_wait()' can return without a post to
> the semaphore;

It is semaphore which is not a condition variable, buddy.

> it can return when internal sem value is 0; think along the
> lines of `EINTR'. The fix for the pseudo-code is fairly simple:
>
> for (;;) {
>   while (sem_wait(&signal) == EINTR);
>   do_BCDwork();
>
> }

Well, a pseudo-code can omit return code handling since we are talking
about the algorithm.

Best Regards,
Szabolcs

Chris M. Thomasson

unread,
Sep 28, 2008, 5:17:14 PM9/28/08
to

"Szabolcs Ferenczi" <szabolcs...@gmail.com> wrote in message
news:96137cdd-e78d-44ef...@y21g2000hsf.googlegroups.com...

On Sep 28, 10:44 pm, "Chris M. Thomasson" <n...@spam.invalid> wrote:
> > "Szabolcs Ferenczi" <szabolcs.feren...@gmail.com> wrote in message
> >
> > news:e2f3e0ea-83c8-477e...@8g2000hse.googlegroups.com...
> >
> > > On Sep 27, 4:28 am, "lancer6...@yahoo.com" <lancer6...@yahoo.com>
> > > wrote:
> > [...]
> > > // Thread A
> > > while (1)
> > > {
> > > do_Awork();
> > > sem_post(&signal);
> > > }
> >
> > > // Thread B, C, D
> > > while (1)
> > > {
> > > sem_wait(&signal);
> > > do_BCDwork();
> > > }
> >

> Hmmm... Do we have a second forum monkey next to DS? Do you feel you
> have to jump?

lol.


> [...]
>
> That's potentially broken ...

> Still, it is much better than your factually broken attempt here:
> http://groups.google.com/group/comp.programming.threads/msg/233368e9feb5db93

Nope; sem_wait can fail when its interrupted by a signal. My attempt does
not suffer from that. Its too strong for the OP's needs because I failed to
understand that he ensured `do_BCDwork()' is fully thread-safe already.


> > because `sem_wait()' can return without a post to
> > the semaphore;

> It is semaphore which is not a condition variable, buddy.

Your the one who used a POSIX semaphore interface. Obviously you did not
seem to understand that `sem_wait' can return `EINTR' in the presence of a
signal. Therefore, I needed to clarify this point to the OP who might of not
know that either.


> > it can return when internal sem value is 0; think along the
> > lines of `EINTR'. The fix for the pseudo-code is fairly simple:
> >
> > for (;;) {
> > while (sem_wait(&signal) == EINTR);
> > do_BCDwork();
> >
> > }

> Well, a pseudo-code can omit return code handling since we are talking
> about the algorithm.

`EINTR' is a very important return value which is regular overlooked and can
introduce race-conditions and break algorihtms. I needed to point that fact
out. Sorry, buddy.

:^|

Szabolcs Ferenczi

unread,
Sep 28, 2008, 5:23:59 PM9/28/08
to
On Sep 28, 11:17 pm, "Chris M. Thomasson" <n...@spam.invalid> wrote:
> "Szabolcs Ferenczi" <szabolcs.feren...@gmail.com> wrote in message
>
> news:96137cdd-e78d-44ef...@y21g2000hsf.googlegroups.com...
> On Sep 28, 10:44 pm, "Chris M. Thomasson" <n...@spam.invalid> wrote:
>
>
>
> > > "Szabolcs Ferenczi" <szabolcs.feren...@gmail.com> wrote in message
>
> > >news:e2f3e0ea-83c8-477e...@8g2000hse.googlegroups.com...
>
> > > > On Sep 27, 4:28 am, "lancer6...@yahoo.com" <lancer6...@yahoo.com>
> > > > wrote:
> > > [...]
> > > > // Thread A
> > > > while (1)
> > > > {
> > > > do_Awork();
> > > > sem_post(&signal);
> > > > }
>
> > > > // Thread B, C, D
> > > > while (1)
> > > > {
> > > > sem_wait(&signal);
> > > > do_BCDwork();
> > > > }
>
> > Hmmm... Do we have a second forum monkey next to DS? Do you feel you
> > have to jump?
>
> lol.
>
> > [...]
>
> > That's potentially broken ...
> > Still, it is much better than your factually broken attempt here:
> >http://groups.google.com/group/comp.programming.threads/msg/233368e9f...

>
> Nope; sem_wait can fail when its interrupted by a signal. My attempt does
> not suffer from that.

Well, your attempt does not suffer from that because you failed to
recognise that it is simpler to communicate a problem-level event with
a semaphore and you attempted to fix the more complicated version with
the condition variable. However, you failed and your solution is
broken.

> Its too strong for the OP's needs because I failed to
> understand that he ensured `do_BCDwork()' is fully thread-safe already.

You failed much more than that.

Best Regards,
Szabolcs

Chris M. Thomasson

unread,
Sep 28, 2008, 5:33:19 PM9/28/08
to

<lance...@yahoo.com> wrote in message
news:4010f3a7-b66a-4b05...@o40g2000prn.googlegroups.com...

Well, then you can use Szabolcs suggestion of a semaphore. Just keep in mind
that `sem_wait()' can fail "spuriously" with `EINTR'. A lot of programs have
race-conditions because they simply overlook this moment. Luckily, its easy
to work around; something like this is fine:
_________________________________________________________
static int
sem_wait_signal_safe(
sem_t* const this
) {
int status;
do {
status = sem_wait(this);
} while (status == EINTR);
return status;
}
_________________________________________________________

Chris M. Thomasson

unread,
Sep 28, 2008, 5:38:36 PM9/28/08
to
"Szabolcs Ferenczi" <szabolcs...@gmail.com> wrote in message
news:a0742837-09ba-4a74...@79g2000hsk.googlegroups.com...

Sure.


> > Its too strong for the OP's needs because I failed to
> > understand that he ensured `do_BCDwork()' is fully thread-safe already.

> You failed much more than that.

lol.

Chris M. Thomasson

unread,
Sep 28, 2008, 5:46:34 PM9/28/08
to

<lance...@yahoo.com> wrote in message
news:a099c363-65be-4a41...@a29g2000pra.googlegroups.com...

So, do_Awork is a producer right? Humm... Well, a seg-fault does not always
indicate a problem with misusing a condvar. Your usually going to get a
deadlock. If you think that the misuse of a condvar is causing a seg-fault
then its probably because its allowing multiple threads to access a
data-structure which simply cannot tolerate it. Are you sure that the
implementation of the global queue is correct? After you switch over to the
semaphore solution proposes else-thread and run the program, are you still
getting seg-faults? For some reason, I think the problem may be in the
global queue impl...

Chris M. Thomasson

unread,
Sep 28, 2008, 5:49:40 PM9/28/08
to
"Chris M. Thomasson" <n...@spam.invalid> wrote in message
news:PQSDk.4183$Bt7....@newsfe13.iad...

>
> <lance...@yahoo.com> wrote in message
> news:a099c363-65be-4a41...@a29g2000pra.googlegroups.com...
[...]

>
> So, do_Awork is a producer right?

Please clarify... do_Awork and do_BCDwork can run concurrently within the
global queue impl right? I am curious as to what the queue impl looks like.

lance...@yahoo.com

unread,
Sep 28, 2008, 9:01:33 PM9/28/08
to
On Sep 29, 5:49 am, "Chris M. Thomasson" <n...@spam.invalid> wrote:
> "Chris M. Thomasson" <n...@spam.invalid> wrote in messagenews:PQSDk.4183$Bt7....@newsfe13.iad...
>
>
>
> > <lancer6...@yahoo.com> wrote in message

> >news:a099c363-65be-4a41...@a29g2000pra.googlegroups.com...
> [...]
>
> > So, do_Awork is a producer right?

Yes.

>
> Please clarify... do_Awork and do_BCDwork can run concurrently within the
> global queue impl right? I am curious as to what the queue impl looks like.

It's a circular queue. do_Awork and do_BCDwork should be able to run
concurrently. Specifically, do_Awork puts items into the queue and
do_BCDwork removes items from the queue. Ideally, do_Awork should
write to the queue faster than do_BCDwork can read from the queue, and
when this does not happen, i.e. do_BCDwork attempts to read an item
that hasn't been written to the queue yet, it should wait till
do_Awork has completed writing that item to the queue. Also, more than
one thread should run do_BCDwork concurrently, with each thread
reading a different item in the queue, and only one thread runs
do_Awork.

>
> > Humm... Well, a seg-fault does not always indicate a problem with misusing
> > a condvar. Your usually going to get a deadlock. If you think that the
> > misuse of a condvar is causing a seg-fault then its probably because its
> > allowing multiple threads to access a data-structure which simply cannot
> > tolerate it. Are you sure that the implementation of the global queue is
> > correct? After you switch over to the semaphore solution proposes
> > else-thread and run the program, are you still getting seg-faults? For
> > some reason, I think the problem may be in the global queue impl...

The seg fault may also be caused by the consumer threads running
do_BCDwork accessing an item in the queue that hasn't been completely
written to the queue yet, because the consumer threads have been woken
too early by the producer thread. I'm trying to correct this problem.

Chris M. Thomasson

unread,
Sep 29, 2008, 7:59:37 AM9/29/08
to
"Szabolcs Ferenczi" <szabolcs...@gmail.com> wrote in message
news:e2f3e0ea-83c8-477e...@8g2000hse.googlegroups.com...

> On Sep 27, 4:28 am, "lancer6...@yahoo.com" <lancer6...@yahoo.com>
> wrote:
>> Hi all,
>>
>> I would like to know if my understanding on how the program handles
>> pthread_cond_wait() and pthread_cond_signal() is correct.
>>
>> Given the code below,
>>
>> // Thread A
>> while (1)
>> {
>> do_Awork();
>> signal = 1;
>> pthread_cond_signal(&condition);
>> signal = 0;
>>
>> }
>>
>> // Thread B, C, D
>> while (1)
>> {
>> pthread_mutex_lock(&mutex);
>> while (!signal)
>> pthread_cond_wait(&condition, &mutex);
>> do_BCDwork();
>> pthread_mutex_unlock(&mutex);
>>
>> }
>
> When you consider using condition variables, it always helps you if
> you know about the condition variable test:
> http://groups.google.com/group/comp.programming.threads/browse_frm/thread/0ff7ac10adadee22

Forget that sack of crap! Use Relacy:

http://groups.google.ru/group/relacy/web

It works. Any questions?

:^|

[...]

Chris M. Thomasson

unread,
Sep 30, 2008, 6:31:51 AM9/30/08
to
<lance...@yahoo.com> wrote in message
news:597b7a22-235d-4099...@q26g2000prq.googlegroups.com...

> On Sep 29, 5:49 am, "Chris M. Thomasson" <n...@spam.invalid> wrote:
>> "Chris M. Thomasson" <n...@spam.invalid> wrote in
>> messagenews:PQSDk.4183$Bt7....@newsfe13.iad...
>>
>>
>>
>> > <lancer6...@yahoo.com> wrote in message
>> >news:a099c363-65be-4a41...@a29g2000pra.googlegroups.com...
>> [...]
>>
>> > So, do_Awork is a producer right?
>
> Yes.
>
>>
>> Please clarify... do_Awork and do_BCDwork can run concurrently within the
>> global queue impl right? I am curious as to what the queue impl looks
>> like.
>
> It's a circular queue. do_Awork and do_BCDwork should be able to run
> concurrently. Specifically, do_Awork puts items into the queue and
> do_BCDwork removes items from the queue. Ideally, do_Awork should
> write to the queue faster than do_BCDwork can read from the queue, and
> when this does not happen, i.e. do_BCDwork attempts to read an item
> that hasn't been written to the queue yet, it should wait till
> do_Awork has completed writing that item to the queue. Also, more than
> one thread should run do_BCDwork concurrently, with each thread
> reading a different item in the queue, and only one thread runs
> do_Awork.

If your sure that the queue itself does not have a bug, fine. If so, your
experiencing a signaling bug. If not, well, shi%t happens and the queue
needs to be "reexamined"...


>> > Humm... Well, a seg-fault does not always indicate a problem with
>> > misusing
>> > a condvar. Your usually going to get a deadlock. If you think that the
>> > misuse of a condvar is causing a seg-fault then its probably because
>> > its
>> > allowing multiple threads to access a data-structure which simply
>> > cannot
>> > tolerate it. Are you sure that the implementation of the global queue
>> > is
>> > correct? After you switch over to the semaphore solution proposes
>> > else-thread and run the program, are you still getting seg-faults? For
>> > some reason, I think the problem may be in the global queue impl...
>
> The seg fault may also be caused by the consumer threads running
> do_BCDwork accessing an item in the queue that hasn't been completely
> written to the queue yet, because the consumer threads have been woken
> too early by the producer thread. I'm trying to correct this problem.

Well, using a semaphore like Szabolcs suggested would solve that. Since,
according to you, do_Awork and do_BCDwork do not need to be under the
protection of a common mutex, well, then a semaphore would be fine. Your
consumers will not get signaled unless the producer has created something
and _fully_ committed into the queue logic indeed. Have you tried using a
semaphore? Do you still experience a seg-fault? Also, if your using POSIX
semaphore, again, please keep in mind that the error condition `EINTR' can,
and probably WILL, occur every now and then...

0 new messages