У меня есть петля.Внутри этого цикла я пытаюсь определить, инициировано ли чтение или запись в файл с именованным каналом (FIFO) с помощью select()
.
Если инициировано чтение, я вызываю read()
в дескрипторе файла FIFO..
Если запись активирована, я вызываю write()
в дескрипторе файла FIFO
Проблема в том, что если произойдет запись, и я запишу в FIFO, она вызовет чтение.И тогда, когда я читаю из FIFO, он запускает запись.Вызывает бесконечный цикл.
Этот цикл происходит немедленно, если я использую тот же файловый дескриптор в режиме O_RDWR
.Этот цикл происходит после первой записи, если я создаю отдельный дескриптор файла для чтения и записи.
#include <errno.h>
#include <sys/select.h>
#include <stdlib.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
#include <string.h>
int main() {
// Open export fifo
int fd = open("./foo-fifo", O_RDWR | O_CREAT);
if (fd < 0) { // Failed to open
perror("error opening fifo");
}
// Read or write fifo until "quit" is in buffer
while (true) {
fd_set read_fds;
fd_set write_fds;
FD_ZERO(&read_fds);
FD_SET(fd, &read_fds);
FD_ZERO(&write_fds);
FD_SET(fd, &write_fds);
int num_fds = select(fd+1, &read_fds, &write_fds, NULL, NULL);
if (num_fds < 0) { // Failed to select
perror("failed to select fifo fd");
} else if (num_fds == 0) { // Timeout
continue;
}
// If read
if (FD_ISSET(fd, &read_fds)) {
char buf[1000] = "";
if (read(fd, buf, sizeof(buf)) < 0) {
perror("error reading fifo");
}
printf("read: \"%s\"\n", buf);
if (strcmp(buf, "quit\n") == 0) {
break;
}
}
// If write
if (FD_ISSET(fd, &write_fds)) {
char *buf = "foo";
if (write(fd, buf, sizeof(buf)) < 0) {
perror("error writing fifo");
}
printf("write: \"%s\"\n", buf);
}
}
// Close fifo
if (close(fd) < 0) { // Failed to close
perror("failed to close export fifo");
}
return 0;
}
Запустите пример, загрузив код отсюда (GitHub Gist) .Затем запустите:
gcc -o fifo fifo.c
./fifo
На выходе отобразится цикл между чтением и записью:
write: "foo"
read: ""
write: "foo"
read: ""
write: "foo"
...