Cygwin FIFO против родного Linux FIFO - несоответствие в поведении блокировки?

Вопрос задан: 7 месяцев назад Последняя активность: 7 месяцев назад
up 0 down

Показанный код основан на примере использования именованных каналов с некоторого учебного сайта

server.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>

#define FIFO_FILE "MYFIFO"

int main()
{
        int fd;
        char readbuf[80];
        int read_bytes;

        // mknod(FIFO_FILE, S_IFIFO|0640, 0);
        mkfifo(FIFO_FILE, 0777);
        while(1) {
                fd = open(FIFO_FILE, O_RDONLY);
                read_bytes = read(fd, readbuf, sizeof(readbuf));
                readbuf[read_bytes] = '\0';
                printf("Received string: \"%s\". Length is %d\n", readbuf, (int)strlen(readbuf));
        }
        return 0;
}

При выполнении сервера в Windows с использованием Cygwin сервер входит в нежелательный цикл, повторяя то же сообщение. Например, если вы пишете в оболочке:

$ ./server
|

тогда «сервер» ждет клиента, но когда FIFO не пуст, например, писать в новой оболочке

$ echo "Hello" > MYFIFO

затем сервер входит в бесконечный цикл, повторяя строку «Hello»

Received string: "Hello". Length is 4
Received string: "Hello". Length is 4
...

Кроме того, новые строки, записанные в fifo, по-видимому, не читаются сервером. Однако в Linux поведение совсем другое. В Linux сервер печатает строку и ожидает появления новых данных на fifo. В чем причина этого несоответствия?

1 ответ

up 1 down accepted

Вам нужно исправить свой код, чтобы удалить как минимум 3 ошибки:

Вы не делаете close(fd) так что вы получите утечку файлового дескриптора и в конечном итоге не сможете open() новые файлы.

Вы не проверяете значение fd (если он вернется -1 тогда произошла ошибка).

Вы не проверяете значение read (если он вернется -1 тогда произошла ошибка)... а ваши readbuf[read_bytes] = '\0'; не будет делать то, что вы ожидаете в результате.

Когда вы получаете ошибку, то errno скажу вам, что пошло не так.

Эти ошибки, вероятно, объясняют, почему вы продолжаете получать Hello выход (особенно readbuf[read_bytes] проблема).