当生产者不能再提供时停止消费者

时间:2016-04-03 05:58:18

标签: c multithreading pthreads deadlock

这是我的消费者代码,我删除了计算部分,因为它(我认为)无关紧要:

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()

锁定

1 个答案:

答案 0 :(得分:1)

您的问题与传统的消费者/制作人问题本身并没有关系。你的问题是你需要一种方法来执行"工人/消费者"线程。

在这种情况下,我可以通过发送" empty / null"来完成此操作。向消费者提供文件。您可以根据需要定义为空。

管理使用者的线程需要为创建的永久消费者线程发送一次此信号。

程序可能如下所示:

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