15-18 Вызов shm_open открывает объект разделяемой памяти, который должен уже существовать (поскольку не указан флаг O_CREAT). Память отображается в адресное пространство процесса вызовом mmap, после чего дескриптор закрывается.

Открытие семафора

19 Открываем именованный семафор.

Блокирование семафора и увеличение счетчика

20-26 Параметр командной строки позволяет указать количество увеличений счетчика. Каждый раз мы выводим предыдущее значение счетчика вместе с идентификатором процесса, поскольку одновременно работают несколько экземпляров программы.

Запустим сначала сервер, а затем три экземпляра программы-клиента в фоновом режиме.

solaris % server shm1 sem1

solaris % client1 shm1 sem110000 client1 shm1 sem110000 client1 shm1 sem1 10000

[2] 17976        интерпретатор выводит идентификаторы процессов

[3] 17977

[4] 17978

pid 17977: 0     и этот процесс запускается первым

pid 17977: 1

. . .            процесс 17977 продолжает работу

pid 17977: 32

pid 17976: 33    ядро переключается междупроцессами

. . .            процесс 17976 продолжает работу

pid 17976: 707

pid 17978: 708   ядро переключается между процессами

. . .            процесс 17978 продолжает работу

pid 17978: 852

pid 17977: 853   ядро переключается между процессами

. . .            и т.д.

pid 17977: 29997

pid 17977: 29999 последнее выводимое значение. Оно оказывается правильным.

<p>13.6. Отправка сообщений на сервер</p>

Изменим наше решение задачи производителей и потребителей следующим образом. Сначала запускается сервер, создающий объект разделяемой памяти, в который клиенты записывают свои сообщения. Сервер просто выводит содержимое этих сообщений, хотя задачу можно и обобщить таким образом, чтобы он выполнял действия, аналогичные демону syslog, который описан в главе 13 [24]. Мы называем группу отправляющих сообщения процессов клиентами, потому что по отношению к нашему серверу они ими и являются, однако эти клиенты могут являться серверами по отношению к другим приложениям. Например, сервер Telnet является клиентом демона syslog, когда отправляет ему сообщения для занесения их в системный журнал.

Вместо передачи сообщений одним из описанных ранее методов (часть 2) будем хранить сообщения в разделяемой памяти. Это, разумеется, потребует какой-либо формы синхронизации действий клиентов, помещающих сообщения, и сервера, читающего их. На рис. 13.2 приведена схема приложения в целом.

Рис. 13.2. Несколько клиентов отправляют сообщения серверу через разделяемую память

Перед нами взаимодействие нескольких производителей (клиентов) и одного потребителя (сервер). Разделяемая память отображается в адресное пространство сервера и каждого из клиентов.

В листинге 13.8 приведен текст заголовочного файла cliserv2.h, в котором определена структура объекта, хранимого в разделяемой памяти.

Листинг 13.8. Заголовочный файл, определяющий содержимое разделяемой памяти

//pxshm/cliserv2.h

1  #include "unpipc.h"

2  #define MESGSIZE 256 /* максимальный размер сообщения в байтах, включая завершающий ноль */

3  #define NMESG 16 /* максимальное количество сообщений */

4  struct shmstruct { /* структура, хранящаяся в разделяемой памяти */

5   sem_t mutex; /* три семафора Posix, размещаемые в памяти */

6   sem_t nempty;

7   sem_t nstored;

8   int nput; /* индекс для следующего сообщения */

9   long noverflow; /* количество переполнений */

10  sem_t noverflowmutex; /* взаимное исключение для счетчика переполнений */

11  long msgoff[NMESG]; /* сдвиг для каждого из сообщений */

12  char msgdata[NMESG * MESGSIZE]; /* сами сообщения */

13 };

Основные семафоры и переменные
Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже