我正在使用pthread来解决生产者 - 消费者问题。基本上,生产者将文件读取到缓冲区,并且消费者(至少一个,但不限于)从缓冲区中获取条目并逐个操作它们。 这是制片人:
//...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而不是广播,但也没有用。
无论如何,这里有什么我想念的吗?
答案 0 :(得分:1)
似乎正在发生的事情是文件被完全读取并且仍有工作要做,但由于生产者不再运行,消费者的等待永远不会完成。
从技术上讲,这不是僵局。这是生产者/消费者线程配置的常见挑战。有多种方法可以解决这个问题。
pthread_cancel
,以便pthread_cond_wait
中止。但是,要想完全正确,这一点很棘手,一般来说,最好避免取消。请注意,如果您有多个消费者,每个消费者都需要在观察到已达到数据结束状态后广播该信号,以便其他消费者也有机会观察它,