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

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

Жанры

Разработка приложений в среде Linux. Второе издание

Троан Эрик В.

Шрифт:

Браузеру легче всего обработать эти файлы, считывая и обрабатывая данные из них (системный вызов

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

Если одно из сетевых подключений является медленным, начинают возникать проблемы. Когда браузер снова считывает из этого файла, он перестает работать, в то время как

read
блокируется в ожидании поступления данных. Не стоит и упоминать, что подобное поведение не является
удобоваримым для пользователя браузера.

Для иллюстрации этих проблем рассмотрим короткую программу, считывающую из двух файлов,

p1
и
p2
. Для ее испытания откройте три сеанса работы с X-терминалом (или воспользуйтесь тремя виртуальными консолями). Создайте каналы под именами
p1
и
p2
(с помощью команды
mknod
), затем запустите
cat > p1
и
cat > p2
в двух терминалах, одновременно запустив
mpx-blocks
в третьем. После этого набирайте любой текст в каждом окно
cat
и смотрите, как он появляется. Помните, что две команды
cat
не будут записывать данные в каналы до конца строки.

 1: /* mpx-blocks.с */

 2:

 3: #include <fcntl.h>

 4: #include <stdio.h>

 5: #include <unistd.h>

 6:

 7: int main(void) {

 8: int fds[2];

 9: char buf[4096];

10: int i;

11: int fd;

12:

13: if ((fds[0] = open("p1", O_RDONLY) ) < 0) {

14: perror("open p1");

15: return 1;

16: }

17:

18: if ( (fds[1] = open("p2", O_RDONLY)) < 0) {

19: perror("open p2");

20: return 1;

21: }

22:

23: fd = 0;

24: while (1) {

25: /* если данные доступны, прочитать и отобразить их */

26: i = read (fds[fd], buf, sizeof (buf) - 1);

27: if (i < 0) {

28: perror("read");

29: return 1;

30: } else if (!i) {

31: printf("канал закрыт\n");

32: return 0;

33: }

34:

35: buf[i] = '\0';

36: printf ("чтение: %s", buf);

37:

38: /* читать из другого файлового дескриптора */

39: fd = (fd + 1) % 2;

40: }

41: }

Хотя

программа
mpx-blocks
может считывать одновременно из обоих каналов, это не является особо эффективным. Она считывает из каждого канала по очереди. После запуска программа читает из первого файла, пока в нем доступны данные, второй файл игнорируется вплоть до возврата из
read
для первого файла. Как только произошел возврат, первый файл игнорируется вплоть до чтения данных из второго файла. Этот метод не поддерживает гладкое мультиплексирование данных. На рис. 13.1 показана программа
mpx-blocks
во время выполнения.

Рис. 13.1. Примеры запуска мультиплексной передачи

13.1.1. Неблокируемый ввод-вывод

Как упоминалось в главе 11, неблокируемый файл можно определить с помощью системного вызова

fcntl
. Если медленный файл неблокируемый,
read
сразу же возвращается. Если данные недоступны, она просто возвращает 0. Неблокируемый ввод- вывод предоставляет простое решение мультиплексирования, предотвращая блокирование файловых операций.

Показанная ниже модифицированная версия

mpx-blocks
пользуется преимуществом неблокируемого ввода-вывода для более гладкого переключения между
p1
и
p2
.

 1: /* mpx-nonblock.c */

 2:

 3: #include <errno.h>

 4: #include <fcntl.h>

 5: #include <stdio.h>

 6: #include <unistd.h>

 7:

 8: int main(void) {

 9: int fds[2];

10: char buf[4096];

11: int i;

12: int fd;

13:

14: /* открыть оба канала в неблокирующем режиме */

15: if ((fds[0] = open("p1", O_RDONLY | O_NONBLOCK)) < 0) {

16: perror("open p1");

17: return 1;

18: }

19:

20: if ((fds[1] = open("p2", O_RDONLY | O_NONBLOCK)) < 0) {

21: perror("open p2");

22: return 1;

23: }

24:

25: fd = 0;

26: while (1) {

27: /* если данные доступны, прочитать и отобразить их */

28: i = read(fds[fd], buf, sizeof (buf) - 1);

29: if ((i < 0) && (errno ! = EAGAIN)) {

30: perror("read");

31: return 1;

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

Отмороженный 8.0

Гарцевич Евгений Александрович
8. Отмороженный
Фантастика:
постапокалипсис
рпг
аниме
5.00
рейтинг книги
Отмороженный 8.0

Газлайтер. Том 14

Володин Григорий Григорьевич
14. История Телепата
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Газлайтер. Том 14

Ермак. Телохранитель

Валериев Игорь
2. Ермак
Фантастика:
альтернативная история
7.00
рейтинг книги
Ермак. Телохранитель

Матабар IV

Клеванский Кирилл Сергеевич
4. Матабар
Фантастика:
фэнтези
5.00
рейтинг книги
Матабар IV

Сборник коротких эротических рассказов

Коллектив авторов
Любовные романы:
эро литература
love action
7.25
рейтинг книги
Сборник коротких эротических рассказов

Идеальный мир для Лекаря 19

Сапфир Олег
19. Лекарь
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 19

Дочь моего друга

Тоцка Тала
2. Айдаровы
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Дочь моего друга

Свет Черной Звезды

Звездная Елена
6. Катриона
Любовные романы:
любовно-фантастические романы
5.50
рейтинг книги
Свет Черной Звезды

Кодекс Крови. Книга IV

Борзых М.
4. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга IV

Идеальный мир для Лекаря 22

Сапфир Олег
22. Лекарь
Фантастика:
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Идеальный мир для Лекаря 22

Попаданка в академии драконов 4

Свадьбина Любовь
4. Попаданка в академии драконов
Любовные романы:
любовно-фантастические романы
7.47
рейтинг книги
Попаданка в академии драконов 4

Сердце Дракона. Том 12

Клеванский Кирилл Сергеевич
12. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.29
рейтинг книги
Сердце Дракона. Том 12

Лолита

Набоков Владимир Владимирович
Проза:
классическая проза
современная проза
8.05
рейтинг книги
Лолита

Сводный гад

Рам Янка
2. Самбисты
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Сводный гад