A condition variable is appropriate here- actually, a pair of condition variables, because the consumer also needs to block if the queue is empty:
pthread_cond_t qu_empty_cond = PTHREAD_COND_INITIALIZER;
pthread_cond_t qu_full_cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t qu_mutex = PTHREAD_MUTEX_INITIALIZER;
void *num_consumer(void *arg)
{
while(1) {
int num;
pthread_mutex_lock(&qu_mutex);
while (qu.size() < 1)
pthread_cond_wait(&qu_empty_cond, &qu_mutex);
num = qu.pop();
if (qu.size() < 5)
pthread_cond_signal(&qu_full_cond);
pthread_mutex_unlock(&qu_mutex);
do_something_with(num);
}
}
int main()
{
pthread_create(&tid, NULL, num_consumer, NULL);
while(1) {
int num;
produce(&num);
pthread_mutex_lock(&qu_mutex);
queue.push(num);
pthread_cond_signal(&qu_empty_cond);
if (qu.size() >= 10)
do {
pthread_cond_wait(&qu_full_cond, &qu_mutex);
} while (qu.size() >= 5);
pthread_mutex_unlock(&qu_mutex);
}
}
Note that that when the producer waits on the condition variable, the queue mutex is atomically released.