【问题标题】:Reader threads not exiting - Posix Pthreads阅读器线程未退出 - Posix Pthreads
【发布时间】:2019-09-10 10:14:57
【问题描述】:

我必须使用 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);
    }
}

【问题讨论】:

    标签: c multithreading pthreads posix pthread-join


    【解决方案1】:

    您只展示了代码的草图,我无法进行完整的分析,但即使是草图也显示了您的方法存在缺陷。当编写器使新数据可用时,它会解除对 一个 阅读器的阻塞:

                pthread_cond_signal(&qElement);
    

    如果在作者发布最后一篇作品时两个读者都在等待(看起来很可能),那么当作者终止时,一个读者将等待。

    最好的解决方案是使用pthread_cond_broadcast() 代替pthread_cond_signal() 或在pthread_cond_signal() 之外使用。用后者代替前者应该没问题,因为你的读者无论如何都应该保护自己免受虚假唤醒(看起来确实如此)。但是,如果您愿意,您可以让编写器在它终止之前广播,或者让主线程在它加入编写器之后广播。

    此外,我倾向于认为您使用的简历比实际需要的要多得多。很可能您可以只使用一个,这样编写和推理都会更简单。

    【讨论】:

    • 抱歉,我只是不想粘贴所有代码。我在这里这样做了:pastebin.com/31NR4vT9 - 我试图在第 93 行用广播替换信号,但问题仍然存在。
    • @A1_,如果问题中提供的代码没有充分表达问题,而且听起来好像没有,那么要做的就是将其减少到 minimal reproducible example(或从头开始构建一个 MCVE)来重现该问题,并更新您的问题以呈现该问题。我们通常不接受依赖仅来自外部站点的资源或代码的问题。
    猜你喜欢
    • 1970-01-01
    • 2011-06-08
    • 1970-01-01
    • 2011-07-30
    • 1970-01-01
    • 2011-06-02
    • 1970-01-01
    • 2012-05-10
    • 1970-01-01
    相关资源
    最近更新 更多