我必须使用 posix pthreads 创建一个解决读写器问题的解决方案,我已将代码压缩为与 C 混合的伪代码,以减少代码的大小。
写入器线程正常完成,但读取器线程永远不会终止/退出,因此读取器加入将永远等待,并且程序挂起。
我认为这与读取器函数中的等待条件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()
或与其一起使用。用后者代替前者应该没问题,因为无论如何你的读者都应该保护自己免受虚假唤醒(看起来确实如此)。不过,如果您愿意,可以让编写器在终止之前进行广播,或者让主线程在加入编写器之后进行广播。
此外,我倾向于认为您使用的简历比实际需要的多得多。您很可能只使用一个,这样编写和推理都会更简单。
关于c - 读取器线程未退出 - Posix Pthreads,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55773743/