Alcott
Alcott

Reputation: 18605

how to block a thread and resume it

Here is what I want to do: there is a main thread producing numbers and put them into a queue, it fires a child thread consuming the numbers in the queue.

The main thread should stop producing numbers if the queue's size grows more than 10, and it should resume number production if the queue's size goes down less than 5.

queue<int> qu;

void *num_consumer(void *arg)
{
    while(1) {
        //lock qu
        int num = qu.pop();
        //unlock qu
        do_something_with(num);
    }
}

int main()
{
    pthread_create(&tid, NULL, num_consumer, NULL);
    while(1) {
        int num;
        produce(&num);
        //lock qu
        queue.push(num);
        //unlock qu
        if(qu.size() >= 10) {
            //how to block and how to resume the main thread?
        }
    }
}

I might use semaphore to do the job, but any other idea?

Upvotes: 3

Views: 9369

Answers (1)

caf
caf

Reputation: 239321

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.

Upvotes: 5

Related Questions