1

I'm trying to implement producer-consumer model and I got some problem with it. Consider code

int number=0;

void* master(void* p){
    int i;
    pthread_t workers[5];
    for(i=0;i<5;i++)
        pthread_create(&workers[i],NULL,worker,NULL);

    while(1){
        //possible delay

        pthread_mutex_lock(&mutex);
        if(number == LIMIT)
            pthread_cond_wait(&not_full,&mutex);

        number++;
        pthread_cond_signal(&not_empty);
        pthread_mutex_unlock(&mutex);
    }
}

void* worker(void* p){
    while(1){
        pthread_mutex_lock(&mutex);
        if(number == 0)
            pthread_cond_wait(&not_empty,&mutex);

        number--;
        pthread_cond_signal(&not_full);
        pthread_mutex_unlock(&mutex);

        //possible delay
    }
}

Maybe it's obvious to you, but I can't figure out how is it possible that the variable number get's negative which of course lets the worker thread decrement it further. What am I doing wrong?

--EDIT--

Ok one progress is doing while(number==0) instead of if, yet I still don't understand how could it happen that there could be two threads decrementing the variable after getting the not_empty signal while it is less then two.

Pyjong
  • 3,095
  • 4
  • 32
  • 50

1 Answers1

2

I think replacing if with while may be masking a problem rather than solving it. Per Why do pthreads’ condition variable functions require a mutex? the mutex you use with a condition variable is used to protect access to that condition variable. In your case you appear to be using mutex to protect three things: the global number, and two condition variables, not_full and not_empty.

Something you need to realize -- the implementation of pthread_cond_wait() will unlock your mutex, and re-locked it before it returns, and this window of being open is allowing for other threads to get in when you don't want them to. Replacing if with while as you have is one solution, but another is using a second mutex in your worker to protect access to both "number" as well as the conditioned wait.

Community
  • 1
  • 1
mah
  • 39,056
  • 9
  • 76
  • 93
  • Yup, I finally made myself some time to try it out with second mutex and it works too. I will probably use this way in the future since it's kinda "smarter" than that while cycle. Thank you for your answer it is and will be of much use to me. – Pyjong Oct 31 '11 at 20:50