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

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

Шрифт:

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 };

Основные семафоры и переменные

5-8 Три семафора Posix, размещаемых в памяти, используются для того же, для чего семафоры использовались в задаче производителей и потребителей в разделе 10.6. Их имена mutex, nempty, nstored. Переменная nput хранит индекс следующего помещаемого сообщения. Поскольку одновременно работают несколько производителей, эта переменная защищена взаимным исключением и хранится в разделяемой памяти вместе со всеми остальными.

Счетчик переполнений

9-10 Существует вероятность того, что клиент не сможет отправить сообщение из-за отсутствия свободного места для него. Если программа-клиент представляет собой сервер для других приложений (например, сервер FTP или HTTP), она не должна блокироваться в ожидании освобождения места для сообщения. Поэтому программа-клиент будет написана таким образом, чтобы она не блокировалась, но увеличивала счетчик переполнений (noverflow). Поскольку этот счетчик также является общим для всех процессов, он также должен быть защищен взаимным исключением, чтобы его значение не было повреждено.

Сдвиги сообщений и их содержимое

11-12 Массив msgoff содержит сдвиги сообщений в массиве msgdata, в котором сообщения хранятся подряд. Таким образом, сдвиг первого сообщения msgoff[0] = 0, msgoff [1] = 256 (значение MESGSIZE), msgoff [2] = 512 и т. д.

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

В листинге 13.9 приведен текст программы-сервера, которая ожидает помещения сообщений в разделяемую память, а затем выводит их.

Листинг 13.9. Сервер, считывающий сообщения из разделяемой памяти

//pxshm/server2.c

1 #include "cliserv2.h"

2 int

3 main(int argc, char **argv)

4 {

5 int fd, index, lastnoverflow, temp;

6 long offset;

7 struct shmstruct *ptr;

8 if (argc != 2)

9 err_quit("usage: server2 <name>");

10 /* создание объекта разделяемой памяти, установка размера, отображение в память, закрытие дескриптора */

11 shm_unlink(Px_ipc_name(argv[1])); /* ошибка игнорируется */

12 fd = Shm_open(Px_ipc_name(argv[1]), O_RDWR | O_CREAT | O_EXCL, FILE_MODE);

13 ptr = Mmap(NULL, sizeof(struct shmstruct), PROT_READ | PROT_WRITE,

14 MAP_SHARED, fd, 0);

15 Ftruncate(fd, sizeof(struct shmstruct));

16 Close(fd);

17 /* инициализация массива сдвигов */

18 for (index = 0; index < NMESG; index++)

19 ptr->msgoff[index] = index * MESGSIZE;

20 /* инициализация семафоров в разделяемой памяти */

21 Sem_init(&ptr->mutex, 1, 1);

22 Sem_init(&ptr->nempty, 1, NMESG);

23 Sem_init(&ptr->nstored, 1, 0);

24 Sem_init(&ptr->noverflowmutex, 1, 1);

25 /* программа-потребитель */

26 index = 0;

27 lastnoverflow = 0;

28 for (;;) {

29 Sem_wait(&ptr->nstored);

30 Sem_wait(&ptr->mutex);

31 offset = ptr->msgoff[index];

32 printf("index = %d: %s\n", index, &ptr->msgdata[offset]);

  • Читать дальше
  • 1
  • ...
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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