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

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

Шрифт:

33 if (++index >= NMESG)

34 index =0; /* циклический буфер */

35 Sem_post(&ptr->mutex);

36 Sem_post(&ptr->nempty);

37 Sem_wait(&ptr->noverflowmutex);

38 temp = ptr->noverflow; /* не выводим, пока не снимем блокировку */

39 Sem_post(&ptr->noverflowmutex);

40 if (temp != lastnoverflow) {

41 printf("noverflow = %d\n", temp);

42 lastnoverflow = temp;

43 }

44 }

45 exit(0);

46 }

Создание объекта разделяемой памяти

10-16 Сначала делается вызов shm_unlink, чтобы удалить объект с тем же именем, который мог остаться после другого приложения. Затем объект разделяемой памяти создается вызовом shm_open и отображается в адресное пространство процесса вызовом mmap, после чего дескриптор объекта закрывается.

Инициализация массива сдвигов

17-19 Массив сдвигов инициализируется сдвигами сообщений.

Инициализация семафоров

20-24 Инициализируются четыре семафора, размещаемые в объекте разделяемой памяти. Второй аргумент sem_init всегда делается ненулевым, поскольку семафоры будут использоваться совместно несколькими процессами.

Ожидание сообщения, вывод его содержимого

25-36 Первая половина цикла for написана по стандартному алгоритму потребителя: ожидание изменения семафора nstored, установка блокировки для семафора mutex, обработка данных, увеличение значения семафора nempty.

Обработка переполнений

37-43 При каждом проходе цикла мы проверяем наличие возникших переполнений. Сравнивается текущее значение noverflows с предыдущим. Если значение изменилось, оно выводится на экран и сохраняется. Обратите внимание, что значение считывается с заблокированным взаимным исключением noverflowmutex, но блокировка снимается перед сравнением и выводом значения. Идея в том, что нужно всегда следовать общему правилу минимизации количества операций, выполняемых с заблокированным взаимным исключением. В листинге 13.10 приведен текст программы-клиента.

Листинг 13.10. Клиент, помещающий сообщения в разделяемую память

//pxshm/client2.c

1 #include "cliserv2.h"

2 int

3 main(int argc, char **argv)

4 {

5 int fd, i, nloop, nusec;

6 pid_t pid;

7 char mesg[MESGSIZE];

8 long offset;

9 struct shmstruct *ptr;

10 if (argc != 4)

11 err_quit("usage: client2 <name> <#loops> <#usec>");

12 nloop = atoi(argv[2]);

13 nusec = atoi(argv[3]);

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

15 fd = Shm_open(Px_ipc_name(argv[1]), O_RDWR, FILE_MODE);

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

17 MAP_SHARED, fd, 0);

18 Close(fd);

19 pid = getpid;

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

21 Sleep_us(nusec);

22 snprintf(mesg, MESGSIZE, "pid %ld; message %d", (long) pid, i);

23 if (sem_trywait(&ptr->nempty) == –1) {

24 if (errno == EAGAIN) {

25 Sem_wait(&ptr->noverflowmutex);

26 ptr->noverflow++;

27 Sem_post(&ptr->noverflowmutex);

28 continue;

29 } else

30 err_sys("sem_trywait error");

31 }

32 Sem_wait(&ptr->mutex);

33 offset = ptr->msgoff[ptr->nput];

34 if (++(ptr->nput) >= NMESG)

35 ptr->nput = 0; /* циклический буфер */

36 Sem_post(&ptr->mutex);

37 strcpy(&ptr->msgdata[offset], mesg);

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

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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