c - 读取器线程未退出 - Posix Pthreads

标签 c multithreading pthreads posix pthread-join

我必须使用 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/

相关文章:

使用 CSS 自定义 GtkStack 转换

c - 为什么 pthread_cond_signal 有时不起作用?

pthreads - 在 Win7 中使用 MinGW 中的 pthreads

c - 数组指针在线程中如何工作?

C - 标准输入、unix 管道和 EOF

c - 为什么“while(!feof(file))”总是错误的?

c - 应用程序在释放内存时出现段错误

Java,这个线程安全吗

c# - 在 Application_Start 上启动长时间运行的线程时的潜在陷阱

c - pthreads : difference due to malloc and direct declaration