2016-04-03 48 views
2

这里停止消费是我的消费者的代码,我删除了计算的部分,因为它是(我认为)无关:当制片人不能提供了

void *compute() 
{ 
    struct document** document; 
    document = (struct document**)malloc(sizeof(struct document*)); 
    while((hasNextData || counter > 0)) { 
     sem_wait(&full); 
     pthread_mutex_lock(&buffer_access) ; 
     if(remove_document(document)) { 
      fprintf(stderr, "Consumer report error condition\n"); 
      pthread_mutex_unlock(&buffer_access); 
     } 
     else { 
//   pthread_mutex_unlock(&buffer_access); 
//   Compute the document 
     } 
     sem_post(&empty); 
    } 
    free(document); 
    pthread_exit(0); 
} 

我也有将生产documents,并把它们制作人在缓冲区中。如果缓冲区已满,它将等待要处理的文档(它们被remove_document删除)。当输入文件被完全读取时,它停止并且线程退出。

此代码适用于一个或两个消费者线程,但是当更多时,它会死锁。 我认为问题在于等待的信号量。我们假设我们有6个输入行(他们将在缓冲区中创建文档)和10个消费者线程。将创建十个线程来处理仅6个输入。所以如果每个线程处理一个数据,最多会有4个锁定线程?最坏的情况是9个锁定线程?

这是我对这个问题的理解。但我不知道如何防止这种情况,因为我读过的教程使用while(1)作为生产者和消费者的条件。

是否有一个标准/通用的方式来解决消费者 - 生产者问题,当他们不生产/消费(真)时? 或者我应该调整计数器?但我不知道该把条件放在哪里。如果我把它放在外面,我会在处理某些事情之前杀死线程,如果我把它放在里面,它们将被锁定sem_wait()

+0

只是为了记录在案,这是不是“C线”,而是并行线程。 – Dolda2000

+0

我编辑了标题,谢谢 – Dranna

+0

单程:发送信号给每个线程。如果线程在sem_wait上被阻塞,它将会解除阻塞并返回代码应该检查的'EINTR'。如果它不在'sem_wait',它将继续执行。信号处理程序应该设置一个标志来表示线程应该停止处理,while循环应该检查这个标志。 – kaylum

回答

1

你的问题并没有真正与经典的消费者/生产者问题本身相关。你的问题是你需要一种方式来执行“工作者/消费者”线程的受控关闭。

在这种情况下,我可以通过向消费者发送一个“空/空”文件来实现这一点。不管你想要什么,你都可以定义空。

管理消费者的线程需要为曾经创建的消费者线程发送一次该信号。

的过程可能是这个样子:

while(1) 
    { 
     sem_wait(&full); 
     pthread_mutex_lock(&buffer_access) ; 
     if(remove_document(document)) { 
      fprintf(stderr, "Consumer report error condition\n"); 
      pthread_mutex_unlock(&buffer_access); 
      // I would probably exit here too, but thats up to you 
     } 
     else if (isEmptyDoc(document) 
     { 
      // Clean up and exit thread. 
     } 
     else 
     { 
      // Do stuff. 
     } 
     sem_post(&empty); 
    } 
相关问题