我正在使用pthreads解决生产者-消费者问题。基本上,生产者将文件读取到缓冲区,而使用者(至少一个,但不限于此)从缓冲区中获取条目,并逐个操作它们。
这是生产者:

//...Local stuff...
if(file){
    while(fgets(line, 256, file)){
        pthread_mutex_lock(&buffer_mutex);
        while(data->buffer->buffer_items == data->buffer->buffer_size){
            pthread_cond_wait(&buffer_full_cv, &buffer_mutex);}
        data->buffer->buffer_items);
        reads++;
        add_to_head(data->buffer, line);
        pthread_cond_broadcast(&buffer_ready_cv);
        pthread_mutex_unlock(&buffer_mutex);
    }
    pthread_mutex_lock(&buffer_mutex);
    work = 0;
    pthread_mutex_unlock(&buffer_mutex);
    fclose(file);
}


这是消费者:

//...Local stuff...
while(1){
    pthread_mutex_lock(&buffer_mutex);
    while(data->buffer->buffer_items == 0){
        if(work)
            pthread_cond_wait(&buffer_ready_cv, &buffer_mutex);
        else if(!work && !data->buffer->buffer_items)
            pthread_exit(NULL);
    }
    remove_from_tail(data->buffer, string_to_check);
    data->buffer->buffer_items);
    pthread_cond_signal(&buffer_full_cv);
    pthread_mutex_unlock(&buffer_mutex);

    for(unsigned int i = 0; i < data->num_substrings; i++){
        cur_occurrence = strstr(string_to_check, data->substrings[i]);
        while(cur_occurrence != NULL){
            pthread_mutex_lock(&buffer_mutex);
            data->occurrences[i]++;
            cur_occurrence++;
            cur_occurrence = strstr(cur_occurrence, data->substrings[i]);
            pthread_mutex_unlock(&buffer_mutex);
        }
    }
}


似乎正在发生的事情是文件已被完全读取,并且仍有工作要做,但是由于生产者不再运行,因此消费者中的等待永远不会结束。


  PS .:我也尝试了pthread_cond_signal而不是广播,但也没有用。


无论如何,我这里缺少什么吗?

最佳答案

似乎正在发生的事情是文件已被完全读取,并且仍有工作要做,但是由于生产者不再运行,因此消费者中的等待永远不会结束。


从技术上讲,这不是僵局。这是生产者/使用者线程配置的常见挑战。有多种方法可以解决此问题。


您可以使用一个特殊的缓冲区值(与空缓冲区分开),该值指示生产者已完成。 (如果您有多个使用者,则必须在缓冲区中保留此特殊值。)尽管这样的带内信令有时易于实现,但通常并不是一个好的设计。
如果您有多个生产者,则可能应将缓冲区与正在运行的生产者数量的计数器结合起来,从本质上在缓冲区中添加一个信号量。如果生产者数量达到零,则消费者需要退出。
加入所有使用者之后,产生生产者和使用者的线程可以使用pthread_cancel,因此pthread_cond_wait被中止。但是,要完全正确,这是棘手的,通常最好避免取消。


请注意,如果您有多个使用者,则每个人都需要在观察到达到数据结束状态后广播信号,以便其他使用者也有机会观察到它,

关于c - 使用pthread在生产者-消费者中出现死锁,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47107738/

10-11 22:11
查看更多