pthread_cond_wait segmentation fault

0

001

I tried to make a producer of 'items' but my implementation crashes at
pthread_cond_wait ... I really tried looking at everything and put
print statements throughout my code, but there it just crashes. I did
put the wait within a mutex. This code isn't complete, but the
relevant parts are in there (I assume). Any idea what I did wrong?
This is the first time I used condition variables. Oh yeah... another
question: is it possible to wait on multiple condition variables (and
continue when one of them changes)? So that I can stop a thread
independent of whether or not it is waiting for something?


Sincerely,

Stéphane Thibaud

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <pthread.h> // needed for pthreads
#include <unistd.h> // for usleep()

#include "prodcons.h"

static unsigned int prodCount = 0; // The number of produces items
static unsigned int bufferHead = 0; // Indicates the first free place
in buffer or undefined when prodCount = BUFFER_SIZE
static unsigned int inBufferCnt = 0; // Number of items in buffer
static pthread_mutex_t bufferLock;
static pthread_cond_t bufferNotFull;
static pthread_cond_t availForCons[NROF_CONSUMERS]; // Conditions
variables for the availability of items on the belt (per consumer)
static const unsigned short int ALL_ONES = 0xFFFF;
static int producing = 1;

static void rsleep (int t);

static void * producer (/*void * arg*/)
{
ITEM item; // a produced item

while (prodCount < NROF_ITEMS) // While not all items are produced
{
rsleep (PRODUCER_SLEEP_FACTOR);

item = (random() % NROF_CONSUMERS) + (prodCount << NROF_BITS_DEST);
prodCount++;
pthread_mutex_lock(&bufferLock);
printf("justlocked\n");
if(inBufferCnt == BUFFER_SIZE)
{
printf("full buffer\n");
pthread_cond_wait(&bufferNotFull, &bufferLock);
printf("not full anymore\n");
}
buffer[bufferHead] = item;
bufferHead = (bufferHead + 1) % BUFFER_SIZE;
inBufferCnt++;
if(inBufferCnt == 1)
{
printf("consumer signaled\n");
pthread_cond_signal(&availForCons[buffer[bufferHead - 1] & ~
(ALL_ONES << NROF_BITS_DEST)]);
}
printf("%04x\n", item); // write info to stdout, putting it inside
the CS ensures no two threads write to stdout at the same time
printf("unlockingnext\n");
pthread_mutex_unlock(&bufferLock);
}

producing = 0;

return NULL;
}
 
M

Mark Bluemel

I tried to make a producer of 'items' but my implementation crashes at
pthread_cond_wait ... I really tried looking at everything and put
print statements throughout my code, but there it just crashes. I did
put the wait within a mutex.

This is really not the best place to ask questions about threading,
which are not part of the core C language, but rather provided in a
variety of fairly platform-specific ways.

However, I think you may need to initialise your mutexes and condition
variables - see the pthread_mutex_init() and pthread_cond_init() calls
for more detail.
This code isn't complete, but the
relevant parts are in there (I assume). Any idea what I did wrong?
This is the first time I used condition variables. Oh yeah... another
question: is it possible to wait on multiple condition variables (and
continue when one of them changes)? So that I can stop a thread
independent of whether or not it is waiting for something?

These questions would be much better asked in a newsgroup related to
threading - comp.programming.threads would be a good start and
comp.unix.programmer may be relevant as you seem to be using POSIX
threads.
 
G

gwowen

It's difficult (impossible) to be sure but

static void * producer (/*void * arg*/)

you do need that void* arg. i.e.

static void * producer (void * arg);

It's what pthread_create expects - a function that takes a void
pointer and returns a void pointer (which enables arbitrary data to be
passed back and forth, as long as the threads know in advance...

PS: Please ignore Kenny McCormack. He's a troll (and worse, a truly
dull troll with only one joke).
 
0

001

This is really not the best place to ask questions about threading,
which are not part of the core C language, but rather provided in a
variety of fairly platform-specific ways.

However, I think you may need to initialise your mutexes and condition
variables - see the pthread_mutex_init() and pthread_cond_init() calls
for more detail.


These questions would be much better asked in a newsgroup related to
threading - comp.programming.threads would be a good start and
comp.unix.programmer may be relevant as you seem to be using POSIX
threads.

Thanks for your response. I'll post it there too... Initialization is
done before this thread was created, but isn't visible in the code I
posted (I'll post that too).
 
0

001

It's difficult (impossible) to be sure but

static void * producer (/*void * arg*/)

you do need that void* arg. i.e.

static void * producer (void * arg);

It's what pthread_create expects - a function that takes a void
pointer and returns a void pointer (which enables arbitrary data to be
passed back and forth, as long as the threads know in advance...

PS: Please ignore Kenny McCormack.  He's a troll (and worse, a truly
dull troll with only one joke).

Thanks a lot for pointing out that removing that argument violates the
posix definition of the function. It didn't solve the problem however,
this is the output to be exact:

0701
unlockingnext
justlocked
0800
unlockingnext
justlocked
0902
unlockingnext
justlocked
full buffer
856324 [unknown (0xDC)] prodcons 2272 _cygtls::handle_exceptions:
Error while d
umping state (probably corrupted stack)
Segmentation fault (core dumped)

Sincerely,

Stéphane
 
D

David Resnick

I tried to make a producer of 'items' but my implementation crashes at
pthread_cond_wait ... I really tried looking at everything and put
print statements throughout my code, but there it just crashes. I did
put the wait within a mutex. This code isn't complete, but the
relevant parts are in there (I assume). Any idea what I did wrong?
This is the first time I used condition variables. Oh yeah... another
question: is it possible to wait on multiple condition variables (and
continue when one of them changes)? So that I can stop a thread
independent of whether or not it is waiting for something?

Sincerely,

Stéphane Thibaud

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <pthread.h> // needed for pthreads
#include <unistd.h>     // for usleep()

#include "prodcons.h"

static unsigned int prodCount = 0; // The number of produces items
static unsigned int bufferHead = 0; // Indicates the first free place
in buffer or undefined when prodCount = BUFFER_SIZE
static unsigned int inBufferCnt = 0; // Number of items in buffer
static pthread_mutex_t bufferLock;
static pthread_cond_t bufferNotFull;
static pthread_cond_t availForCons[NROF_CONSUMERS]; // Conditions
variables for the availability of items on the belt (per consumer)
static const unsigned short int ALL_ONES = 0xFFFF;
static int producing = 1;

static void rsleep (int t);

static void * producer (/*void * arg*/)
{
    ITEM    item;   // a produced item

    while (prodCount < NROF_ITEMS) // While not all items are produced
    {
        rsleep (PRODUCER_SLEEP_FACTOR);

                item = (random() % NROF_CONSUMERS) + (prodCount << NROF_BITS_DEST);
                prodCount++;
                pthread_mutex_lock(&bufferLock);
                printf("justlocked\n");
                if(inBufferCnt == BUFFER_SIZE)
                {
                    printf("full buffer\n");
                    pthread_cond_wait(&bufferNotFull, &bufferLock);
                        printf("not full anymore\n");
                }
                buffer[bufferHead] = item;
                bufferHead = (bufferHead + 1) % BUFFER_SIZE;
                inBufferCnt++;
                if(inBufferCnt == 1)
                {
                    printf("consumer signaled\n");
                    pthread_cond_signal(&availForCons[buffer[bufferHead - 1] & ~
(ALL_ONES << NROF_BITS_DEST)]);
                }
                printf("%04x\n", item); // write info to stdout, putting it inside
the CS ensures no two threads write to stdout at the same time
                printf("unlockingnext\n");
                pthread_mutex_unlock(&bufferLock);
    }

        producing = 0;

        return NULL;

}

The stuff quoted below from the linux man page *may* apply. Followups
set to comp.unix.programmer, which is a better place for you to get
help on this. I'd also suggest running it under valgrind if you have
it available, if you do have uninitialized variables/overruns/etc that
will help you discover them. You could also check the returns of the
lock/cond_wait calls for failure, as it is possible under some
circumstances and it could help you figure out what is going on.

****************************
Some implementations, particularly on a multi-processor,
may sometimes cause multiple threads to wake up when the condition
variable is signaled simultaneously on different processors.

In general, whenever a condition wait returns, the thread has
to re-evaluate the predicate associated with the condition wait to
determine whether it can safely proceed, should wait again,
or should declare a timeout. A return from the wait does not imply
that the associated predicate is either true or false.

It is thus recommended that a condition wait be enclosed in the
equivalent of a "while loop" that checks the predicate.
*****************************

-David
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
473,767
Messages
2,569,570
Members
45,045
Latest member
DRCM

Latest Threads

Top