Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Message from discussion pthread condition variable deadlock?
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Alexander Terekhov  
View profile  
 More options Sep 13 2001, 4:01 am
Newsgroups: comp.programming.threads
From: Alexander Terekhov <terek...@web.de>
Date: Thu, 13 Sep 2001 10:01:32 +0200
Local: Thurs, Sep 13 2001 4:01 am
Subject: Re: pthread condition variable deadlock?

Andy Barclay wrote:

> I am writing some course material on multi-threading using posix
> threads. I seem to be having some difficulty with posix condition
> variables.

> The problem is that the program deadlocks. On a single processor, it
> will run for quite a while (several hundred thousand itterations)
> before deadlocking. On a multi-processor, it deadlocks much more
> quickly.

> I've been programming long enough that I'm 99% sure its a bug in my
> code and not a problem on either of the operating systems that I have
> tried it on (Linux and Solaris).

> Anyway, if anyone can help me, it would be appreciated.

> /* solution to producer/consumer problem */
> #include ?stdio.h?
> #include ?pthread.h?

> #define BUFFERSIZE 5

> int buffer[BUFFERSIZE];
> int produced=0;
> int consumed=0;
> volatile int nitems=0;
> pthread_cond_t buffernotfull,buffernotempty;
> pthread_mutex_t buffernotfullmutex,buffernotemptymutex;

> void *producer(void *tmp)
> {
>         while(1)
>         {
>                 pthread_mutex_lock(?buffernotfullmutex);
>                 while (nitems?=BUFFERSIZE)
>                         pthread_cond_wait(?buffernotfull,?buffernotfullmutex);
>                 buffer[produced]++;
>                 produced=(produced+1)%BUFFERSIZE;
>                 nitems++;
>                 pthread_cond_signal(?buffernotempty);
>                 pthread_cond_signal(?buffernotfull);
>                 pthread_mutex_unlock(?buffernotfullmutex);
>         }
> }

> void *consumer(void *tmp)
> {
>         while(1)
>         {
>                 pthread_mutex_lock(?buffernotemptymutex);
>                 while (nitems?=0)
>                         pthread_cond_wait(?buffernotempty,?buffernotemptymutex);
>                 printf("%d\n",buffer[consumed]);
>                 consumed=(consumed+1)%BUFFERSIZE;
>                 nitems--;
>                 pthread_cond_signal(?buffernotfull);
>                 pthread_cond_signal(?buffernotempty);
>                 pthread_mutex_unlock(?buffernotemptymutex);
>         }
> }

> int main()
> {
>         pthread_t prodtid,contid;
>         int i;

>         /* initialize the buffer to 0 */
>         for (i=0; i?BUFFERSIZE; i++)
>                 buffer[i]=0;

>         /* initialize the condition variables and mutexes*/
>         pthread_cond_init(?buffernotempty,NULL);
>         pthread_cond_init(?buffernotfull,NULL);
>         pthread_mutex_init(?buffernotemptymutex,NULL);
>         pthread_mutex_init(?buffernotfullmutex,NULL);

>         pthread_create(?prodtid,NULL,producer,NULL);
>         pthread_create(?contid,NULL,consumer,NULL);

>         pthread_join(prodtid,NULL);
>         pthread_join(contid,NULL);
> }

you do not need volatiles, two mutexes and
double signaling (notempty&notfull) in both
producer and consumer routines..

/* solution to producer/consumer problem */
#include <stdio.h>
#include <pthread.h>

pthread_mutex_t mutex;
pthread_cond_t notfull,notempty;

#define BUFFERSIZE 5

int buffer[BUFFERSIZE];
const char* buffer2[BUFFERSIZE];
int produced=0;
int consumed=0;
int nitems=0;
int finish=0;

void* producer(void* name)
{
        while(1)
        {
                pthread_mutex_lock(&mutex);
                while (nitems == BUFFERSIZE && !finish)
                        pthread_cond_wait(&notfull,&mutex);
                if (finish)
                        break;
                buffer[produced]++;
                buffer2[produced] = (const char*)name;
                nitems++;
                produced=(produced+1)%BUFFERSIZE;
                pthread_mutex_unlock(&mutex);
                pthread_cond_signal(&notempty);
        }
        pthread_mutex_unlock(&mutex);
        return NULL;

}

void* consumer(void* name)
{
        while(1)
        {
                pthread_mutex_lock(&mutex);
                while (nitems == 0 && !finish)
                        pthread_cond_wait(&notempty,&mutex);
                if (finish && nitems == 0)
                        break;
                printf("%d %s %s\n",buffer[consumed],
                                    buffer2[consumed],
                                    (const char*)name);
                consumed=(consumed+1)%BUFFERSIZE;
                nitems--;
                pthread_mutex_unlock(&mutex);
                pthread_cond_signal(&notfull);
        }
        pthread_mutex_unlock(&mutex);
        return NULL;

}

int main()
{
        pthread_t prodtid[2],constid[3];
        int i;

        /* initialize the buffer to 0 */
        for (i=0; i < BUFFERSIZE; i++)
                buffer[i]=0;

        /* initialize mutex and condition variables */
        pthread_mutex_init(&mutex,NULL);
        pthread_cond_init(&notempty,NULL);
        pthread_cond_init(&notfull,NULL);

        pthread_create(prodtid+0,NULL,producer,"PROD-1");
        pthread_create(prodtid+1,NULL,producer,"PROD-2");
        pthread_create(constid+0,NULL,consumer,"CONS-1");
        pthread_create(constid+1,NULL,consumer,"CONS-2");
        pthread_create(constid+2,NULL,consumer,"CONS-3");

Sleep( 1000 ); // 1 sec

        pthread_mutex_lock(&mutex);
        finish = 1;
        pthread_mutex_unlock(&mutex);

        pthread_cond_broadcast(&notfull);
        pthread_cond_broadcast(&notempty);

        pthread_join(prodtid[0],NULL);
        pthread_join(prodtid[1],NULL);
        pthread_join(constid[0],NULL);
        pthread_join(constid[1],NULL);
        pthread_join(constid[2],NULL);

        pthread_cond_destroy(&notempty);
        pthread_cond_destroy(&notfull);
        pthread_mutex_destroy(&mutex);

        return 0;

}

regards,
alexander.

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.