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

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

Жанры

UNIX: взаимодействие процессов

Стивенс Уильям Ричард

Шрифт:

Следующим шагом будет использование двух потоков (или процессов) и двух буферов. Это называется классическим решением с двойной буферизацией; схема его изображена на рис. 10.14.

Рис. 10.14. Копирование файла двумя потоками с двумя буферами

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

На рис. 10.15 изображена временная диаграмма процесса с двойной буферизацией. Считывающий поток помещает данные в буфер № 1, а затем уведомляет записывающий о том, что буфер готов к обработке. Затем считывающий процесс помещает данные в буфер № 2, а записывающий берет их из буфера № 1.

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

Обратите внимание, что операции записи выполняются так быстро, как только возможно. Они разделены промежутками времени всего лишь в 2 единицы, тогда как в предыдущих примерах между ними проходило 9 единиц времени (рис. 10.10 и 10.13). Это может оказаться выгодным при работе с некоторыми устройствами типа накопителей на магнитной ленте, которые функционируют быстрее, если данные записываются с максимально возможной скоростью (это называется потоковым режимом — streaming mode).

Рис. 10.15. Процесс с двойной буферизацией

Интересно, что задача с двойной буферизацией представляет собой лишь частный случай общей задачи производителей и потребителей.

Изменим нашу программу так, чтобы использовать несколько буферов. Начнем с решения из листинга 10.11, в котором использовались размещаемые в памяти семафоры. Мы получим даже не двойную буферизацию, а работу с произвольным числом буферов (задается NBUFF). В листинге 10.18 даны глобальные переменные и функция main.

Листинг 10.18. Глобальные переменные и функция main

//pxsem/mycat2.c

1 #include "unpipc.h"

2 #define NBUFF 8

3 struct { /* общие данные */

4 struct {

5 char data[BUFFSIZE]; /* буфер */

6 ssize_t n; /* объем буфера */

7 } buff[NBUFF]; /* количество буферов */

8 sem_t mutex, nempty, nstored; /* семафоры, а не указатели */

9 } shared;

10 int fd; /* входной файл, копируемый в стандартный поток вывода */

11 void *produce(void *), *consume(void *);

12 int

13 main(int argc, char **argv)

14 {

15 pthread_t tid_produce, tid_consume;

16 if (argc != 2)

17 err_quit("usage: mycat2 <pathname>");

18 fd = Open(argv[1], O_RDONLY);

19 /* инициализация трех семафоров */

20 Sem_init(&shared.mutex, 0, 1);

21 Sem_init(&shared.nempty, 0, NBUFF);

22 Sem_init(&shared.nstored, 0, 0);

23 /* один производитель, один потребитель */

24 Set_concurrency(2);

25 Pthread_create(&tid_produce, NULL, produce, NULL); /* reader thread */

26 Pthread_create(&tid_consume, NULL, consume, NULL); /* writer thread */

27 Pthread_join(tid_produce, NULL);

28 Pthread_join(tid_consume, NULL);

29 Sem_destroy(&shared.mutex);

30 Sem_destroy(&shared.nempty);

31 Sem_destroy(&shared.nstored);

32 exit(0);

33 }

Объявление нескольких буферов

2-9 Структура shared содержит массив структур buff, которые состоят из буфера и его счетчика. Мы создаем NBUFF таких буферов.

Открытие входного файла

18 Аргумент командной строки интерпретируется как имя файла, который копируется в стандартный поток вывода.

В листинге 10.19 приведен текст функций produce и consume.

Листинг 10.19. Функции produce и consume

//pxsem/mycat2.c

34 void *

35 produce(void *arg)

36 {

37 int i;

38 for (i = 0;;) {

39 Sem_wait(&shared.nempty); /* Ожидание освобождения места в буфере */

40 Sem_wait(&shared.mutex);

41 /* критическая область */

42 Sem_post(&shared.mutex);

43 shared.buff[i].n = Read(fd, shared.buff[i].data, BUFFSIZE);

44 if (shared.buff[i].n == 0) {

45 Sem_post(&shared.nstored); /* еще один объект */

46 return(NULL);

47 }

48 if (++i >= NBUFF)

49 i = 0; /* кольцевой буфер */

50 Sem_post(&shared.nstored); /* еще один объект */

51 }

52 }

53 void *

54 consume(void *arg)

55 {

56 int i;

57 for (i = 0;;) {

58 Sem_wait(&shared.nstored); /* ожидание появления объекта для обработки */

59 Sem_wait(&shared.mutex);

60 /* критическая область */

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

Мы – Гордые часть 8

Машуков Тимур
8. Стальные яйца
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Мы – Гордые часть 8

Королевский крест

Панов Вадим Юрьевич
10. Тайный Город
Фантастика:
боевая фантастика
9.09
рейтинг книги
Королевский крест

Я все еще граф. Книга IX

Дрейк Сириус
9. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Я все еще граф. Книга IX

Мужчина моей судьбы

Ардова Алиса
2. Мужчина не моей мечты
Любовные романы:
любовно-фантастические романы
8.03
рейтинг книги
Мужчина моей судьбы

Девяностые приближаются

Иванов Дмитрий
3. Девяностые
Фантастика:
попаданцы
альтернативная история
7.33
рейтинг книги
Девяностые приближаются

Холод смерти

Макдональд Росс
11. Лью Арчер
Детективы:
крутой детектив
5.00
рейтинг книги
Холод смерти

Метатель. Книга 2

Тарасов Ник
2. Метатель
Фантастика:
боевая фантастика
попаданцы
рпг
фэнтези
фантастика: прочее
постапокалипсис
5.00
рейтинг книги
Метатель. Книга 2

Неудержимый. Книга XVIII

Боярский Андрей
18. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Неудержимый. Книга XVIII

Курс 1. Сентябрь

Фокс Гарри
1. Маркатис
Фантастика:
аниме
фэнтези
сказочная фантастика
5.00
рейтинг книги
Курс 1. Сентябрь

Герой

Бубела Олег Николаевич
4. Совсем не герой
Фантастика:
фэнтези
попаданцы
9.26
рейтинг книги
Герой

Баоларг

Кораблев Родион
12. Другая сторона
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Баоларг

Наследие Маозари 4

Панежин Евгений
4. Наследие Маозари
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Наследие Маозари 4

Без масок

Метельский Николай Александрович
10. Унесенный ветром
Фантастика:
боевая фантастика
6.60
рейтинг книги
Без масок

Крестоносец

Ланцов Михаил Алексеевич
7. Помещик
Фантастика:
героическая фантастика
попаданцы
альтернативная история
6.25
рейтинг книги
Крестоносец