1

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

//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吗?如果是,这个信号会去哪里?以及我的其他工人的样子(规范形式)?

4

1 回答 1

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

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

于 2013-05-14T08:40:45.907 回答