读者 - 写作者对pthreads的问题导致只有1个读者

问题描述 投票:1回答:2

我的任务是使用posix pthreads创建一个读者 - 作者问题的解决方案。我产生了3位读者和1位作家。

任务规范要求一次向队列2添加值(写入者)。读者一次出列一个队列(当队列中存在值时)。队列已经过测试并且有效。

我遇到的问题是在运行程序时,它导致大多数时间只有1个读取器线程实际读取。有时重复执行将导致使用所有3个读者。但大多数时候它只使用了1个读者。我不确定为什么会出现这种奇怪的行为。

提前致谢。

Expected (Sometimes): 
TID: -684419328
TID: -684419328
TID: -673929472
TID: -673929472
TID: -694909184
TID: -694909184
...
Actual (Sometimes): 
TID: -684419328
TID: -684419328
TID: -684419328
TID: -684419328
TID: -684419328
TID: -684419328
...
pthread_cond_t qServiced = PTHREAD_COND_INITIALIZER;
pthread_cond_t qElement = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
#include "rw.h"
#include "queue.h"

queue* q; 

void* reader()
{
    int serviced = 0; 
    int x; 

    while(!fin)
    {
        pthread_mutex_lock(&mutex);
        counter++; 

        while(isEmpty(q))
        {
            pthread_cond_signal(&qEmpty);
            pthread_cond_wait(&qElement, &mutex); e 
        }

        printf("TID: %d\n", (int)pthread_self());

        num* n = dequeue(q); //Take one task 

        printf("Num1: %d\n", n->num1);
        printf("Num2: %d\n", n->num2);

        serviced++;
        pthread_cond_signal(&qServiced); //Signal that task has been serviced
        pthread_mutex_unlock(&mutex);
    }
}
c pthreads producer-consumer
2个回答
1
投票

以下提议的代码仅适用于'read()'线程,但应该让您了解如何编写线程。

void* reader( void *arg )
{
    int *fin = (int*)arg;

    int serviced = 0; 

    while( !(*fin) )
    {
        printf("TID: %d\n", (int)pthread_self());

        pthread_mutex_lock(&mutex);
        counter++; 
        num* n = dequeue(q); //Take one task 
        pthread_mutex_unlock(&mutex);

        if( n )
        {
            printf("Num1: %d\n", n->num1);
            printf("Num2: %d\n", n->num2);
            serviced++;
        }

        else
        {
            printf( "no queue entries available\n" );
            sleep(1);
        }
    }
    pthread_exit( NULL );
}

请注意,只有在线程执行可能导致“竞争”条件的操作时,才会锁定互斥锁。

建议的代码假设(因为队列处理代码从未发布),如果队列为空,dequeue()返回NULL

注意:当没有可用的队列条目时,线程会休眠一段时间

这假设main()函数在调用pthread_create()时将'fin'的地址作为参数传递


0
投票

线程由调度程序在一个调度机制中调度。但作为一名程序员,你应该假设它可以是任何随机的方式和代码。

通过说“随机方式”,我的意思是所有线程都可以在程序过程中安排一次,或者在整个过程中只安排一个线程。

线程可能以随机方式进行调度。我希望这回答了你的问题。

如果您想要一种特定的执行方式(例如:所有线程在第二次读取线程之前读取一次),那么您必须相应地进行编码。您可以使用互斥锁,信号量,条件信号,标志以及所有这些的组合来实现此目的。

© www.soinside.com 2019 - 2024. All rights reserved.