【问题标题】:pthread synchronization on two consumers one producer两个消费者一个生产者上的 pthread 同步
【发布时间】:2013-05-14 16:40:45
【问题描述】:

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

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

【问题讨论】:

    标签: c multithreading pthreads


    【解决方案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;
    }
    

    b.使用consumer2 中的现有条件queueSignalPop 变量等待事件,并使用广播 代替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;
    }
    

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

    【讨论】:

      猜你喜欢
      • 2016-09-03
      • 1970-01-01
      • 2015-07-31
      • 1970-01-01
      • 2023-03-06
      • 1970-01-01
      • 2014-04-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多