Как реализовать Readers Writers, используя несколько писателей и несколько читателей - PullRequest
0 голосов
/ 31 мая 2018

Следующий код написан для получения целых чисел из файла в буфер и чтения их из буфера.Есть два потока записи, которые читают целое число из файла в буфер, и два потока чтения, которые читают целые числа из буфера.Размер буфера равен 5, и в файле может быть любое количество целых чисел.Потоки записи должны записать все целые числа в файле в буфер, а потоки чтения должны прочитать все целые числа в файле через буфер.Читатели не имеют прямого доступа к файлу.Поскольку размер буфера равен 5, когда пишущие записывают данные в буфер и он заполняется, я поместил pthread_cond_signal(&r), чтобы сообщить читателю, что он должен начать чтение.Но читатели продолжают печатать нули без остановки.Я закомментировал часть чтения и часть работы писателей, но она не напечатала 1-е целое число файла, и оба потока писателя прочитали окончательное целое число.(поток писателя один прочитал 100, поток писателя 2 прочитал 100. Таким образом, буфер содержит две 100). Может кто-нибудь указать мне ошибку?

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#define BUF_SIZE 5


pthread_mutex_t m;
pthread_cond_t  r;
pthread_cond_t w;
FILE *fp;

int cnt_r= 0;
int flag =0;
int value;
int buf[BUF_SIZE];
int cnt = 0;
int z = 0;



void *read(void *parm);
void *write(void *parm);

int main(int argc, char argv[])
{

    pthread_t rid[2];
    pthread_t wid[2];

    pthread_cond_init(&r,NULL);
    pthread_cond_init(&w,NULL);


    if ((fp = fopen("/home/bhagi/2/shared_data.txt", "r")) == NULL)
        fprintf(stderr, "Couldn't find the file");


    for( int i = 0; i< 2; i++)
    {
        printf("Writer %d Starts \n",i+1);
        pthread_create(&wid[i], NULL, write,i);
    }


    for(int i = 0; i < 2; i++)
    {
        printf("Reader %d Starts \n",i+1);
        pthread_create(&rid[i],NULL,read,i);
    }

    for(int i = 0; i < 2; i++)
    {
        pthread_join(rid[i],NULL);
    }


    for(int i = 0; i < 2; i++)
    {
        pthread_join(wid[i], NULL);
    }

    fclose(fp);


    return 0;
}

void *read(void *parm)
{

    int y = (int)parm;
    int cnt_r = 0;

    pthread_mutex_lock(&m);

        while (cnt == -1)
        {
            printf("Reader %d waits \n",y+1);
            pthread_cond_wait(&r, &m);
        }
        cnt++;

    printf("Reader %d Access CS\n",y+1);
     while(flag != -1)
     {
         for(int i = 0; i < 5;i++)
         {
             printf("%d ",buf[i]);
             cnt_r++;
             sleep(1);

         }
     printf("\n %d \n",cnt_r);
     }


     cnt--;
     if(cnt == 0)
        pthread_cond_signal(&w);

    if(cnt_r != 0)
    {
        pthread_cond_signal(&r);
        printf("Reader %d Signal Reader\n",y +1);
    }
     pthread_mutex_unlock(&m);



}

void *write(void *parm)
{

    int x = (int)parm;
    int cnt_w = 0;

    while(fscanf(fp,"%d",&value) == 1)
    {

        pthread_mutex_lock(&m);
        while(cnt!= 0) {
            printf("Writer %d waits \n", x + 1);
            pthread_cond_wait(&w, &m);
        }
        cnt++;

        printf("Writer %d access cs \n",x+1);
        cnt = 0;
        pthread_cond_signal(&w);


        if(z == 5)
        {
            z = 0;
            pthread_cond_signal(&r);


        }

        buf[z] = value;
        printf("buf = %d\n",buf[z]);
        ++z;
        cnt_w++;


        sleep(1);
        printf("%d\n",cnt_w);



        pthread_mutex_unlock(&m);


    }

    flag = -1;

}

1 Ответ

0 голосов
/ 01 июня 2018

Поскольку размер буфера равен 5, когда писатели записывают данные в буфер, и он заполняется, я помещаю pthread_cond_signal(&r)

Это имеет вещи задом наперед.Общий шаблон множественного чтения-записи:

  • автор (ы) ждут, пока буфер не заполнится не , запишут столько, сколько могут, затем сигнализируют читателю;
  • считыватели ждут, пока буфер не станет не пустым, затем прочитают столько, сколько могут, затем подадут сигнал автору записи.

Вам понадобитсячтобы увеличить это, чтобы ваши читатели знали, когда выходить:

  • автор (ы) ждут, пока буфер не заполнится не , затем напишите столько, сколько они могут, затем подайте сигналчитательЕсли записывающее устройство достигает EOF, оно устанавливает флаг конца файла и сигнализирует все считыватели;
  • считыватели ожидают, пока буфер не станет не пустымили установлен флаг конца файла.В случае, если буфер не пуст, они затем читают столько, сколько могут, а затем сигнализируют записывающему устройству;в случае, если установлен флаг конца файла, они выходят.

С точки зрения конкретных проблем в вашем текущем коде, два, которые мне выделяются:

  • flag доступны авторам без удержания мьютекса (это может быть причиной вашего бесконечного цикла в читателях, поскольку компилятор может предположить, что flag никогда не изменяется, пока читатель удерживает мьютекс);
  • value должна быть локальной переменной в записывающих устройствах, но она является общей (и доступ к ней несинхронизирован) - это, вероятно, причина того, что ваши писатели оба видят одно и то же число из файла.
...