Чтение онлайн

на главную - закладки

Жанры

Основы программирования в Linux
Шрифт:

Несмотря на то, что этот предел не слишком важен в простом случае с одним записывающим каналом FIFO и одним читающим FIFO, очень распространено использование одного канала FIFO, позволяющего разным программам отправлять запросы к этому единственному каналу FIFO. Если несколько разных программ попытаются писать в FIFO в одно и то же время, жизненно важно, чтобы блоки данных из разных программ не перемежались друг с другом, т. е. каждая операция write должна быть "атомарной". Как это сделать?

Если вы ручаетесь, что все ваши запросы

write
адресованы блокирующему каналу FIFO и их размер меньше
PIPE_BUF
байтов, система гарантирует, что данные никогда не будут разделены. Вообще это неплохая идея — ограничить объем данных, передаваемых через FIFO блоком в
PIPE_BUF
байтов, если вы не используете единственный пишущий и единственный читающий процессы.

Выполните упражнение 13.12.

Упражнение 13.12. Связь процессов с помощью каналов FIFO

Для того чтобы увидеть, как несвязанные процессы могут общаться с помощью именованных каналов, вам понадобятся две отдельные программы fifo3.c и fifo4.c.

1. Первая программа — поставщик. Она создает канал, если требуется, и затем записывает в него данные как можно быстрее.

Примечание

Поскольку пример иллюстративный, нас не интересуют конкретные данные, и мы не беспокоимся об инициализации буфера, В обоих листингах затененные строки содержат изменения, внесенные в программу fifo2.c помимо удаления кода со всеми аргументами командной строки.

#include <unistd.h>

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <fcntl.h>

#include <limits.h>

#include <sys/types.h>

#include <sys/stat.h>

#define FIFO_NAME "/tmp/my_fifo"

#define BUFFER_SIZE PIPE_BUF

#define TEN_MEG (1024 * 1024 * 10)

int main {

 int pipe_fd;

 int res;

 int open_mode = O_WRONLY;

 int bytes_sent = 0;

 char buffer[BUFFER_SIZE + 1];

 if (access(FIFO_NAME, F_OK) == -1) {

res = mkfifo(FIFO_NAME, 0777);

if (res != 0) {

fprintf(stderr, "Could not create fifo %s\n", FIFO_NAME);

exit(EXIT_FAILURE);

}

 }

 printf("Process %d opening FIFO O_WRONLY\n", getpid);

 pipe_fd = open(FIFO_NAME, open_name);

 printf("Process %d result %d\n", getpid, pipe_fd);

 if (pipe_fd != -1) {

while (bytes_sent < TEN_MEG) {

res = write(pipe_fd, buffer, BUFFER_SIZE);

if (res == -1) {

fprintf(stderr, "Write error on pipe\n);

exit(EXIT_FAILURE);

}

bytes_sent += res;

}

(void)close(pipe_fd);

 } else {

exit(EXIT_FAILURE);

 }

 printf("Process %d finished\n", getpid);

 exit(EXIT_SUCCESS);

}

2. Вторая программа, потребитель, гораздо проще. Она читает и выбрасывает данные из канала FIFO.

#include <unistd.h>

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <fcntl.h>

#include <limits.h>

#include <sys/types.h>

#include <sys/stat.h>

#define FIFO_NAME "/tmp/my_fifo"

#define BUFFER_SIZE PIPE_BUF

int main {

 int pipe_fd;

 int res;

 int open_mode = O_RDONLY;

 char buffer[BUFFER_SIZE - 1];

 int bytes_read = 0;

 memset(buffer, '\0', sizeof(buffer));

 printf("Process %d opening FIFO O_RDONLY\n", getpid);

Поделиться:
Популярные книги

Северные сказки

Сборник
Детские:
сказки
5.00
рейтинг книги
Северные сказки

Американские боги. Король горной долины. Сыновья Ананси

Гейман Нил
Фантастика:
научная фантастика
8.30
рейтинг книги
Американские боги. Король горной долины. Сыновья Ананси

Война

Рус Дмитрий
6. Играть, чтобы жить
Фантастика:
фэнтези
боевая фантастика
рпг
8.71
рейтинг книги
Война

Дневник (1887-1910)

Ренар Жюль
Проза:
проза прочее
4.00
рейтинг книги
Дневник (1887-1910)

Детские инфекционные болезни. Полный справочник

Коллектив авторов
Научно-образовательная:
медицина
6.25
рейтинг книги
Детские инфекционные болезни. Полный справочник

Я не царь. Книга XXIV

Дрейк Сириус
24. Дорогой барон!
Фантастика:
юмористическое фэнтези
аниме
попаданцы
5.00
рейтинг книги
Я не царь. Книга XXIV

Первый среди равных. Книга V

Бор Жорж
5. Первый среди Равных
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Первый среди равных. Книга V

Инкарнатор

Прокофьев Роман Юрьевич
1. Стеллар
Фантастика:
боевая фантастика
рпг
7.30
рейтинг книги
Инкарнатор

На Берлин!

Дорничев Дмитрий
2. Моё пространственное убежище
Фантастика:
фэнтези
боевая фантастика
рпг
постапокалипсис
5.56
рейтинг книги
На Берлин!

Неучтенный

Муравьёв Константин Николаевич
1. Неучтенный
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
8.25
рейтинг книги
Неучтенный

Враг Короны

Бушков Александр Александрович
10. Сварог
Фантастика:
героическая фантастика
8.53
рейтинг книги
Враг Короны

Кодекс Охотника. Книга XXIV

Винокуров Юрий
24. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XXIV

Старый, но крепкий

Крынов Макс
1. Культивация без насилия
Фантастика:
рпг
уся
попаданцы
5.00
рейтинг книги
Старый, но крепкий

Гроза богов

Мазуров Дмитрий
10. Громовая поступь
Фантастика:
фэнтези
рпг
5.00
рейтинг книги
Гроза богов