pthread同步两个消费者一个生产者

时间:2013-05-14 03:20:21

标签: c multithreading pthreads

我有一个工作线程处理工作项的队列。

//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);

现在我希望thread2使用add_item_into_list()中插入的数据,但前提是项目已添加到列表中。请注意,该列表是永久性的,在整个程序期间不能清空或释放。

所以我的问题是:我需要另一个pthread_cond_signal吗?如果是的话,这个信号会在哪里?以及我的其他工作人员的样子(规范形式)?

1 个答案:

答案 0 :(得分:1)

我看到了解决问题的两种可能方法:

一个。为列表引入另一个条件变量(例如signalList),以便consumer2线程等待它上面的事件。在这种情况下,consumer1必须发出两次信号:一次在queueSignalPop上,一次在signalList上:

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

湾使用queueSignalPop内的现有条件consumer2变量等待事件,并使用广播而不是consumer1内的信号。广播意味着条件变量上的所有等待线程都将被唤醒:

// 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;
}

我建议采用第一种方法,因为它更好地区分每个条件变量的目的。