当生产者不能再提供时停止消费者
stopping consumer when producer can't provide anymore
这是我的消费者代码,我删除了计算部分,因为它(我认为)不相关:
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 个消费者线程。将创建 10 个线程来仅处理 6 个输入。那么如果每个线程处理一个数据,最多会有 4 个锁定线程?最坏情况下有 9 个锁定线程?
这就是我对问题的理解。但我不知道如何防止这种情况发生,因为我阅读的教程在生产者和消费者中都使用 while(1) 作为条件。
当他们不 produce/consume while(true) 时,是否有 standard/common 解决消费者-生产者问题的方法?
或者我应该调整计数器?但我看不出把条件放在哪里。如果我把它放在诡计之外,我会在它们处理某些东西之前杀死线程,如果我把它放在里面,它们将被 sem_wait()
锁定
您的问题与经典 consumer/producer 问题本身并没有真正的关系。您的问题是您需要一种方法来执行 "worker/consumer" 线程的受控关闭。
在这种情况下,我可能会通过向消费者发送 "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 );
}
这是我的消费者代码,我删除了计算部分,因为它(我认为)不相关:
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 个消费者线程。将创建 10 个线程来仅处理 6 个输入。那么如果每个线程处理一个数据,最多会有 4 个锁定线程?最坏情况下有 9 个锁定线程?
这就是我对问题的理解。但我不知道如何防止这种情况发生,因为我阅读的教程在生产者和消费者中都使用 while(1) 作为条件。
当他们不 produce/consume while(true) 时,是否有 standard/common 解决消费者-生产者问题的方法?
或者我应该调整计数器?但我看不出把条件放在哪里。如果我把它放在诡计之外,我会在它们处理某些东西之前杀死线程,如果我把它放在里面,它们将被 sem_wait()
您的问题与经典 consumer/producer 问题本身并没有真正的关系。您的问题是您需要一种方法来执行 "worker/consumer" 线程的受控关闭。
在这种情况下,我可能会通过向消费者发送 "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 );
}