当前位置: 动力学知识库 > 问答 > 编程问答 >

c - pthread synchronization on two consumers one producer

问题描述:

I have a worker thread processing a queue of work items.

//producer

void push_into_queue(char *item) {

pthread_mutex_lock (&queueMutex);

if(workQueue.full) { // full }

else{

add_item_into_queue(item);

pthread_cond_signal (&queueSignalPush);

}

pthread_mutex_unlock(&queueMutex);

}

// consumer1

void* worker(void* arg) {

while(true) {

pthread_mutex_lock(&queueMutex);

while(workQueue.empty)

pthread_cond_wait(&queueSignalPush, &queueMutex);

item = workQueue.front; // pop from queue

add_item_into_list(item);

// do I need another signal here for thread2?

pthread_cond_signal(&queueSignalPop);

pthread_mutex_unlock(&queueMutex);

}

return NULL;

}

pthread_create (&thread1, NULL, (void *) &worker, NULL);

Now I would like to have thread2 consume the data inserted in add_item_into_list() but only if items have been added to the list. Note that the list is permanent and can't be emptied nor freed for the entire duration of the program.

So my question is: do I need another pthread_cond_signal?, if yes, where would this signal go? and how my other worker would look like (canonical form)?

网友答案:

I see 2 possible ways of solving the problem:

a. Introduce another condition variable (e.g. signalList) for the list, so that consumer2 thread would wait for events on it. In this case consumer1 have to signal twice: once on queueSignalPop and once on signalList:

// consumer1
void* worker(void* arg) {
    while(true) {
        // ...
        pthread_cond_signal(&queueSignalPop);
        pthread_cond_signal(&signalList);
        pthread_mutex_unlock(&queueMutex);
    }   
    return NULL;
}

b. Use existing condition queueSignalPop variable inside consumer2 to wait for events, and use broadcast instead of signal inside consumer1. Broadcast means all the waiting threads on condition variable will wake up:

// consumer1
void* worker(void* arg) {
    while(true) {
        // ...
        pthread_cond_broadcast(&queueSignalPop);
        pthread_mutex_unlock(&queueMutex);
    }   
    return NULL;
}
// consumer2
void* worker2(void* arg) {
    while(true) {
        while(list.empty)
            pthread_cond_wait(&queueSignalPop, &queueMutex);
        // ...
    }   
    return NULL;
}

I would propose to go for the first approach, since it better distinguish the purpose of each condition variable.

分享给朋友:
您可能感兴趣的文章:
随机阅读: