我写过这个制作人/消费者问题解决方案。它似乎工作,除了无限循环。我的印象是pthread_exit(NULL);
会让它停止,但老实说,我已经迷茫和迷茫。有人能指出我如何停止循环的正确方向吗?
#include<stdio.h>
#include<string.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
#include<iostream>
#include<semaphore.h>
#define BUFFSIZE 10
using namespace std;
int buffer[BUFFSIZE];
int size; //current buffer size
int n = 0, m = 0;
pthread_mutex_t Mutex = PTHREAD_MUTEX_INITIALIZER;
sem_t Available;
sem_t Buffer; //indicates if buffer is full
//----------------------------------------------------------------//
void *Consumers(void *argument)
{
int con_id = *((int *) argument);
while(1)
{
if(size == 0)
{
cout << "Queue is empty." << endl;
}
sem_wait(&Available);
pthread_mutex_lock(&Mutex);
size--;
cout << "Con " << con_id << ": Product removed from buffer" << endl;
//for(int i = 0; i < size; i++)
//{
// cout << Buffer[i] << " ";
//}
cout << endl;
pthread_mutex_unlock(&Mutex);
sem_post(&Buffer);
}
return(NULL);
}
//----------------------------------------------------------------//
void *Producers(void *argument)
{
int item = 8;
int pro_id = *((int *) argument);
while(1)
{
sem_wait(&Buffer);
pthread_mutex_lock(&Mutex);
//Buffer[size] = item;
cout << "Item added" << endl;
size++;
pthread_mutex_unlock(&Mutex);
sem_post(&Available);
}
return(NULL);
}
//----------------------------------------------------------------//
int main()
{
cout << "Enter number of producers: " << endl;
scanf("%d", &n);
cout << "Enter number of consumers: " << endl;
scanf("%d", &m);
//get number of producers(int n), and consumers(int m)
sem_init(&Available, 0, 0);
sem_init(&Buffer, 0, BUFFSIZE);
pthread_t *con = new pthread_t[m];
int *thread_args_c = new int[m];
for(int i = 0; i < n; i++)
{
thread_args_c[i] = i;
pthread_create(&con[i], NULL, Consumers, (void*) &i);
}
pthread_t *pro = new pthread_t[n];
int *thread_args_p = new int[n];
for(int i = 0; i < n; i++)
{
thread_args_p[i] = i;
pthread_create(&pro[i], NULL, Producers, (void*) &i);
pthread_join(con[i], NULL);
}
pthread_exit(NULL);
}
答案 0 :(得分:1)
不确定您的期望。 pthread_exit
出现在main的末尾(并且完全不需要,因为main仍在退出),但是你的enless循环内部线程永远不会让main到达这一点(因为你加入了消费者线程)。 / p>
此外,您的创建和加入模型具有愚蠢的意义 - 在您创建生产者之后,加入消费者线程的重点是什么?
最后,但不是租约,你没有加入生产者线程。
答案 1 :(得分:0)
循环不会停止,因为代码中没有逻辑来实际退出循环。
由于pthread_join
暂停调用线程直到目标退出,因此进程停滞不前。见documentation for pthread_join
如果您不关心实际终止线程并返回主线程,只需删除对pthread_join
的调用即可。该进程应终止,因为主线程已退出。
要实际正确终止循环,您需要设置内部或外部触发器。在一定次数的迭代之后,您可以在内部循环退出。为此,您将while(x<=y)
代替while(1)
。
你也可以让它变得更复杂,并让主线程在外部发出信号,希望其他线程关闭。当您准备退出时,可以让主线程设置一个(volatile
)布尔值,并让其他线程break
基于它进行循环。如果您关心退出的Atomicity,则需要使用锁来保护布尔值。