Вход/Регистрация
UNIX: взаимодействие процессов
вернуться

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

Шрифт:

Теперь информация передается между клиентом и сервером в такой последовательности:

■ сервер получает доступ к объекту разделяемой памяти, используя для синхронизации семафор (например);

■ сервер считывает данные из файла в разделяемую память. Второй аргумент вызова read (адрес буфера) указывает на объект разделяемой памяти;

■ после завершения операции считывания клиент уведомляется сервером с помощью семафора;

■ клиент записывает данные из объекта разделяемой памяти в выходной файл. 

Рис. 12.2. Копирование файла через разделяемую память

Этот сценарий иллюстрирует рис. 12.2.

Из этого рисунка видно, что копирование данных происходит всего лишь дважды: из входного файла в разделяемую память и из разделяемой памяти в выходной файл. Мы нарисовали два прямоугольника штриховыми линиями; они подчеркивают, что разделяемая память принадлежит как адресному пространству клиента, так и адресному пространству сервера.

Концепции, связанные с использованием разделяемой памяти через интерфейсы Posix и System V, похожи. Первый интерфейс описан в главе 13, а второй — в главе 14.

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

Сначала мы подчеркнем, что память разделяется между родительским и дочерним процессами при вызове fork. В пpoгрaммe из листинга 12.1 [1] родительский и дочерний процессы по очереди увеличивают глобальный целочисленный счетчик count.

1

Все исходные тексты, опубликованные в этой книге, вы можете найти по адресу http://www.piter.com/download.

Листинг 12.1. Увеличение глобального счетчика родительским и дочерним процессами

//shm/incr1.c

1 #include "unpipc.h"

2 #define SEM_NAME "mysem"

3 int count = 0;

4 int

5 main(int argc, char **argv)

6 {

7 int i, nloop;

8 sem_t *mutex;

9 if (argc != 2)

10 err_quit("usage: incr1 <#loops>");

11 nloop = atoi(argv[1]);

12 /* создание, инициализация и удаление семафора */

13 mutex = Sem_open(Px_ipc_name(SEM_NAME), O_CREAT | O_EXCL, FILE_MODE, 1);

14 Sem_unlink(Px_ipc_name(SEM_NAME));

15 setbuf(stdout, NULL); /* stdout не буферизуется */

16 if (Fork == 0) { /* дочерний процесс */

17 for (i = 0; i < nloop; i++) {

18 Sem_wait(mutex);

19 printf("child: %d\n", count++);

20 Sem_post(mutex);

21 }

22 exit(0);

23 }

24 /* родительский процесс */

25 for (i = 0; i < nloop; i++) {

26 Sem_wait(mutex);

27 printf("parent: %d\r\", count++);

28 Sem_post(mutex);

29 }

30 exit(0);

31 }

Создание и инициализация семафора

12-14 Мы создаем и инициализируем семафор, защищающий переменную, которую мы считаем глобальной (count). Поскольку предположение о ее глобальности ложно, этот семафор на самом деле не нужен. Обратите внимание, что мы удаляем семафор из системы вызовом sem_unlink, но хотя файл с соответствующим полным именем при этом и удаляется, на открытый в данный момент семафор эта команда не действует. Этот вызов мы делаем для того, чтобы файл был удален даже при досрочном завершении программы.

Отключение буферизации стандартного потока вывода и вызов fork

15 Мы отключаем буферизацию стандартного потока вывода, поскольку запись в него будет производиться и родительским, и дочерним процессами. Это предотвращает смешивание вывода из двух процессов.

16-29 Родительский и дочерний процессы увеличивают глобальный счетчик в цикле заданное число раз, выполняя операции только при установленном семафоре.

Если мы запустим эту программу на выполнение и посмотрим на результат, обращая внимание только на те строки, где система переключается между родительским и дочерним процессами, мы увидим вот что:

  • Читать дальше
  • 1
  • ...
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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