我必须使用posix pthreads为读者编写器问题创建一个解决方案,我已将我的代码缩减为与C混合的伪代码以减小代码的大小。
编写器线程完成正常,但读取器线程永远不会终止/退出所以Reader join
永远等待,程序挂起。
我相信它与阅读器功能中的等待条件pthread_cond_wait(&qElement, &mutex);
有关。它可能正在等待终止的作者线程发出信号。我已经尝试用if(!finished)
封装它,所以只有在编写器仍处于活动状态但仍然没有工作的情况下它才会等待。
我不知道该怎么做,并认为它是我的pthread处理的逻辑错误。
真的很感激帮助。
Global variables in header file :
#define TRUE 1
#define FALSE 0
int finished = FALSE
pthread_cond_t qServiced = PTHREAD_COND_INITIALIZER;
pthread_cond_t qEmpty = PTHREAD_COND_INITIALIZER;
pthread_cond_t qElement = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int main()
{
Create 1 writer thread
Create 2 reader threads
Writer join <- Success
Reader join <- Program hangs here
void* writer()
{
int totalQueued = 0;
int tasks = 20;
while(!finished)
{
pthread_mutex_lock(&mutex);
while(isFull(q))
{
pthread_cond_wait(&qEmpty, &mutex);
}
if(totalQueued < tasks)
{
for(j = 0; j < 2; j++) //Add 2 numbers at a time
{
if(!(isFull(q)))
{
//Assume random numbers added to queue
totalQueued++;
}
}
pthread_cond_signal(&qElement);
pthread_cond_wait(&qServiced, &mutex);
}
else
{
finished = TRUE;
}
pthread_mutex_unlock(&mutex);
}
//Thread exits
}
void* reader()
{
while(!finished)
{
pthread_mutex_lock(&mutex);
while(isEmpty(q)) //If the queue is empty
{
pthread_cond_signal(&qEmpty);
pthread_cond_wait(&qElement, &mutex);
}
int n = dequeue(q);
printf("%d\n", n);
pthread_cond_signal(&qServiced); //Signal that task has been serviced
pthread_mutex_unlock(&mutex);
}
}
您只提供了代码草图,我无法进行完整的分析,但即使草图显示您的方法存在缺陷。当作者提供新数据时,它会解锁一个读者:
pthread_cond_signal(&qElement);
如果两个读者都在等待作者发布最后的作品(可能看起来很可能),那么当作者终止时,一个人将等待。
最好的解决方案围绕使用pthread_cond_broadcast()
而不是pthread_cond_signal()
。将后者替换为前者应该没问题,因为你的读者应该保护自己免受虚假的唤醒(看起来确实如此)。但是,如果您愿意,可以让作者在终止之前进行广播,或者在主要线程加入作者之后进行广播。
另外,我倾向于认为你使用的CV比你实际需要的要多得多。很可能你只能使用一个,这将更容易编写和推理。