C Reader Writer Program, один читатель не читает все данные - PullRequest
0 голосов
/ 03 октября 2019

Я работаю над программой чтения / записи, где есть один писатель для n читателей. У меня проблема, когда несколько читателей, как на скриншоте ниже, не отображают все сообщение из общей памяти.

Выход :

Введите сообщение: Test

Reader1: Test

Reader2: Test

Writer: тестовый тест

Reader1: тестовый

Reader2: тестовый тест

Writer :

enter image description here

Считыватели :

enter image description here

Я попытался добавить переменную count, потому что я предполагаю, что авторыОборот помечается, прежде чем все читатели смогут печатать, и он заставляет писателя выйти из вложенного while () в писателе и остановить читателей от печати.

Есть какие-нибудь предложения, чтобы заставить читателей печатать, будь то флаг или какой-то счет? Ниже также приведены скриншоты циклов записи и чтения.

Устройство чтения:

int main() {
    DataShared data;
    data.turn = 0;
    signal(SIGINT, sigHandler);

    //generates key
    key = ftok("mkey",65);

    //returns an identifier in mId
    if ((mId = shmget(key, SIZE, IPC_CREAT|S_IRUSR|S_IWUSR)) < 0){
    perror("shared memory error");
    exit(1);
    }

    // shmat to attach to shared memory
    if((mPtr = shmat(mId, 0, 0)) == (void*) -1) {
    perror("Can't attach\n");
    exit(1);
    }


    while(1) {
        // request critical section
        while(!data.turn && data.count == 0) {
        //not time for the reader, check if token is changed.
            memcpy(&data, mPtr, sizeof(DataShared));
        }

        data.count++;

        // enter critical section
        usleep(1);
        fprintf(stderr, "Read from memory: %s\n", data.message);
        usleep(1);
        // leave critical section

        data.count--;

        while(data.count > 0){
            ;
        }

        data.turn = 0;
        memcpy(mPtr, &data, sizeof(DataShared));
    };

    return 0;
}

Устройство записи:

int main() {
    DataShared data;
    data.turn = 0;
    data.count = 0;
    signal(SIGINT, sigHandler);

    key = ftok("mkey",65);

    if((shmId = shmget(key, SIZE, IPC_CREAT|S_IRUSR|S_IWUSR)) < 0 ) {
        perror("Error creating shared memory\n");
        exit(1);
    }

    if((shmPtr = shmat(shmId, 0, 0)) == (void*) -1) {
        perror("Can't attach\n");
        exit(1);
    }

    while(1) {
        while (data.turn) {
            memcpy(&data, shmPtr, sizeof(DataShared));
        }

        // enter critical section
        printf("Enter a message: \n" );
        fgets(data.message, 1024, stdin);


        // leave critical section
        printf("Message written to memory: %s\n", data.message);
        data.turn = 1;
        memcpy(shmPtr, &data, sizeof(DataShared));
    };

    return 0;
}

1 Ответ

1 голос
/ 03 октября 2019

Это может быть не объяснение ваших наблюдений, но то, что вы делаете, является подозрительным.

У вас есть несколько процессов, и ОС планирует каждый процесс.

Во-первых, нет никакой гарантии, чтовсе читатели будут читать сообщение. Вполне возможно, что один читатель заканчивает работу, устанавливает флаг в 0 и копирует данные обратно в общую память, прежде чем другой читатель сможет прочитать данные.

Тогда ваш data.count. Он начинается с локальной переменной data автора. там вы не инициализируете data.count, поэтому оно имеет неопределенное значение. В читателях вы устанавливаете его на 0, но он будет перезаписан значением из общей памяти (неопределенное значение). Вы делаете ++, позже - и затем ждете, пока оно станет 0. Как это когда-нибудь станет нулем? Этот читатель может ждать вечно.

...