#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#define FIFO_NAME "/tmp/my_fifo"
int main(int argc, char *argv[]) {
int res;
int open_mode = 0;
int i;
if (argc < 2) {
fprintf(stderr, "Usage: %s <some combination of
O_RDONLY O_WRONLY O_NONBLOCK>n", *argv);
exit(EXIT_FAILURE);
}
2. Полагая, что программа передает тестовые данные, вы задаете параметр open_mode из следующих аргументов:
for(i = 1; i <argc; i++) {
if (strncmp(*++argv, "O_RDONLY", 8) == 0) open_mode |= O_RDONLY;
if (strncmp(*argv, "O_WRONLY", 8) == 0) open_mode |= O_WRONLY;
if (strncmp(*argv, "O_NONBLOCK", 10) == 0) open_mode |= O_NONBLOCK;
}
3. Далее проверьте, существует ли канал FIFO, и при необходимости создайте его. Затем FIFO открывается, и пока программа засыпает на короткое время, выполняется результирующий вывод. В заключение FIFO закрывается.
if (access(FIFO_NAME, F_OK) == -1) {
res = mkfifo(FIFO_NAME, 0777);
if (res != 0) {
fprintf(stderr, "Gould not create fifo %sn", FIFO_NAME);
exit(EXIT_FAILURE);
}
}
printf("Process %d opening FIF0n", getpid());
res = open(FIFO_NAME, open_mode);
printf("Process %d result %dn", getpid(), res);
sleep(5);
if (res != -1) (void)close(res);
printf("Process %d finishedn", getpid());
exit(EXIT_SUCCESS);
}
Как это работает
Эта программа позволяет задать в командной строке комбинации значений O_RDONLY, O_WRONLY и O_NONBLOCK, которые вы хотите применить. Делается это сравнением известных строк с параметрами командной строки и установкой (с помощью |=) соответствующего флага при совпадении строки. В программе используется функция access, проверяющая, существует ли уже файл FIFO, и создающая его при необходимости.
Никогда не уничтожайте FIFO, т.к. у вас нет способа узнать, не использует ли FIFO другая программа.
O_RDONLY и
O_WRONLY без
O_NONBLOCKТеперь у вас есть тестовая программа, и вы можете проверить комбинации пар. Обратите внимание на то, что первая программа, считыватель, помещена в фоновый режим.
$ <b>./fifo2 O_RDONLY &</b>
[1] 152
Process 152 opening FIFO
$ <b>./fifo2 O_WRONLY</b>
Process 153 opening FIFO
Process 152 result 3
Process 153 result 3
Process 152 finished
Process 153 finished
Это, наверное, самое распространенное применение именованных каналов. Оно позволяет читающему процессу стартовать и ждать в вызове open, а затем разрешает обеим программам продолжить выполнение, когда вторая программа откроет канал FIFO. Обратите внимание на то, что и читающий, и пишущий процессы были синхронизированы вызовом open.
Примечание
Когда процесс в ОС Linux заблокирован, он не потребляет ресурсы ЦП, поэтому этот метод синхронизации очень эффективен с точки зрения использования ЦП.
O_RDONLY с
O_NONBLOCK и
O_WRONLYВ следующем примере читающий процесс выполняет вызов open и немедленно продолжается, даже если нет ни одного пишущего процесса. Пишущий процесс тоже немедленно продолжает выполняться после вызова open, потому что канал FIFO уже открыт для чтения.
$ <b>./fifо2 O_RDONLY O_NONBLOCK &</b>
[1] 160
Process 160 opening fifo
$ <b>./fifo2 O_WRONLY</b>
Process 161 opening FIFO
Process 160 result 3
Process 161 result 3
Process 160 finished
Process 161 finished
[1]+ Done ./fifo2 O_RDONLY O_NONBLOCK
Эти два примера — вероятно, самые распространенные комбинации режимов open. Не стесняйтесь использовать программу-пример для экспериментов с другими возможными комбинациями.
Чтение из каналов FIFO и запись в них
Применение режима O_NONBLOCK влияет на поведение вызовов read и write в каналах FIFO.
Вызов read, применяемый для чтения из пустого блокирующего FIFO (открытого без флага O_NONBLOCK), будет ждать до тех пор, пока не появятся данные, которые можно прочесть. Вызов read, применяемый в неблокирующем FIFO, напротив, при отсутствии данных вернет 0 байтов.
Вызов write для записи в полностью блокирующий канал FIFO будет ждать до тех пор, пока данные не смогут быть записаны. Вызов write, применяемый к FIFO, который не может принять все байты, предназначенные для записи, либо: