13.5. Увеличение общего счетчика

13.5. Увеличение общего счетчика

Разработаем программу, аналогичную приведенной в разделе 12.3, — несколько процессов увеличивают счетчик, хранящийся в разделяемой памяти. Итак, мы помещаем счетчик в разделяемую память, а для синхронизации доступа к нему используем именованный семафор. Отличие программы из этого раздела от предыдущей состоит в том, что процессы более не являются родственными. Поскольку обращение к объектам разделяемой памяти Posix и именованным семафорам Posix осуществляется по именам, процессы, увеличивающие общий счетчик, могут не состоять в родстве. Достаточно лишь, чтобы каждый из них знал имя IPC счетчика и чтобы у каждого были соответствующие разрешения на доступ к объектам IPC (области разделяемой памяти и семафору).

В листинге 13.6 приведен текст программы-сервера, которая создает объект разделяемой памяти, затем создает и инициализирует семафор, после чего завершает работу.

Листинг 13.6. Программа, создающая и инициализирующая объект разделяемой памяти и семафор

//pxshm/server1.c

1  #include "unpipc.h"

2  struct shmstruct { /* структура, помещаемая в разделяемую память */

3   int count;

4  };

5  sem_t *mutex; /* указатель на именованный семафор */

6  int

7  main(int argc, char **argv)

8  {

9   int fd;

10  struct shmstruct *ptr;

11  if (argc != 3)

12   err_quit("usage: server1 <shmname> <semname>");

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

14  /* создание shm. установка размера, отображение, закрытие дескриптора */

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

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

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

18   MAP_SHARED, fd, 0);

19  Close(fd);

20  sem_unlink(Px_ipc_name(argv[2])); /* игнорируем ошибку */

21  mutex = Sem_open(Px_ipc_name(argv[2]), O_CREAT | O_EXCL, FILE_MODE, 1);

22  Sem_close(mutex);

23  exit(0);

24 }

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

13-19 Программа начинает работу с вызова shm_unlink, на тот случай, если объект разделяемой памяти еще существует, а затем делается вызов shm_open, создающий этот объект. Его размер устанавливается равным размеру структуры sbmstruct вызовом ftruncate, а затем mmap отображает объект в наше адресное пространство. После этого дескриптор объекта закрывается.

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

20-22 Сначала мы вызываем sem_unlink, на тот случай, если семафор еще существует. Затем делается вызов sem_open для создания именованного семафора и инициализации его единицей. Этот семафор будет использоваться в качестве взаимного исключения всеми процессами, которые будут обращаться к объекту разделяемой памяти. После выполнения этих операций семафор закрывается.

Завершение работы процесса

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

Нам приходится использовать разные имена для семафора и объекта разделяемой памяти. Нет никаких гарантий, что в данной реализации к именам Posix IPC будут добавляться какие-либо суффиксы или префиксы, указывающие тип объекта (очередь сообщений, семафор, разделяемая память). Мы видели, что в Solaris эти типы имен имеют префиксы .MQ, .SEM и .SHM, но в Digital Unix они префиксов не имеют.

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

Листинг 13.7. Программа, увеличивающая значение счетчика в разделяемой памяти

//pxshm/client1.c

1  #include "unpipc.h"

2  struct shmstruct { /* структура, помещаемая в разделяемую память */

3   int count;

4  };

5  sem_t *mutex; /* указатель на именованный семафор */

6  int

7  main(int argc, char **argv)

8  {

9   int fd, i, nloop;

10  pid_t pid;

11  struct shmstruct *ptr;

12  if (argc != 4)

13   err_quit("usage: client1 <shmname> <semname> <#loops>");

14  nloop = atoi(argv[3]);

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  mutex = Sem_open(Px_ipc_name(argv[2]), 0);

20  pid = getpid();

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

22   Sem_wait(mutex);

23   printf("pid %ld: %d ", (long) pid, ptr->count++);

24   Sem_post(mutex);

25  }

26  exit(0);

27 }

Открытие области разделяемойпамяти

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 последнее выводимое значение. Оно оказывается правильным.

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

3.2.3 Увеличение и уменьшение*

Из книги C++ автора Хилл Мюррей

3.2.3 Увеличение и уменьшение* – * Следовало бы переводить как «инкремент» и «декремент», однако мы следовали терминологии, принятой в переводной литратуре по C, поскольку эти операции унаследованы от C. (прим.перев.)Операция ++ используется для явного выражения приращения


7.2.1 Увеличение и Уменьшение

Из книги Мобильный интернет автора Леонтьев Виталий Петрович

7.2.1 Увеличение и Уменьшение Операнд префиксного ++ получает приращение. Операнд дожен быть адресным . Значением является новое значение операда, но оно не адресное. Выражение ++x эквивалентно x+=1. По поводу данных о преобразованиях см. обсуждение операций слжения (#7.4) и


Настройка общего доступа

Из книги Интернет-разведка [Руководство к действию] автора Ющук Евгений Леонидович

Настройка общего доступа Сеть работает, а все подключенные к ней компьютеры видны в папке Сеть и в Центре управления сетями. И вот, предвкушая все прелести сетевой работы, вы щелкаете по значку одного из компьютеров, и… не видите ничего. Доступ к содержимому жестких


Просмотр счетчика посещений сайта

Из книги Информатика и информационные технологии: конспект лекций автора Цветкова А В

Просмотр счетчика посещений сайта Неочевидный для многих, но иногда крайне полезный ресурс при изучении сайта компании – счетчик посещений этого сайта. Он позволяет отслеживать, сколько посетителей и откуда приходят на сайт, а также участвовать в рейтингах.Счетчик


4. Регистры общего назначения

Из книги Информатика и информационные технологии автора Цветкова А В

4. Регистры общего назначения Все регистры этой группы позволяют обращаться к своим «младшим» частям. Использовать для самостоятельной адресации можно только младшие 16– и 8-битные части этих регистров. Старшие 16 бит этих регистров как самостоятельные объекты


40. Регистры общего назначения

Из книги AutoCAD 2009 для студента. Самоучитель автора Соколова Татьяна Юрьевна

40. Регистры общего назначения Все регистры этой группы позволяют обращаться к своим «младшим» частям. Использовать для самостоятельной адресации можно только младшие 16– и 8-битные части этих регистров. Старшие 16 бит этих регистров как самостоятельные объекты


Увеличение объектов

Из книги UNIX: взаимодействие процессов автора Стивенс Уильям Ричард

Увеличение объектов Команда LENGTHEN, которая осуществляет увеличение объектов, вызывается из падающего меню Modify ? Lengthen.Действие команды LENGTHEN не распространяется на замкнутые объекты.Запросы команды LENGTHEN: Select an object or [DElta/Percent/Total/DYnamic]: – выбрать объект или один из ключей Current


12.3. Увеличение счетчика в отображаемом в память файле

Из книги Системное программирование в среде Windows автора Харт Джонсон М

12.3. Увеличение счетчика в отображаемом в память файле Изменим программу в листинге 12.1 (которая не работала) таким образом, чтобы родительский и дочерний процессы совместно использовали область памяти, в которой хранится счетчик. Для этого используем отображение файла в


Настройка спин-счетчика

Из книги Визуальное моделирование электронных схем в PSPICE автора Хайнеманн Роберт

Настройка спин-счетчика Обычно, если в результате выполнения функции EnterCriticalSection поток обнаруживает, что объект CS уже принадлежит другому потоку, он входит в ядро и остается блокированным до тех пор, пока не освободится объект CRITICAL_SECTION, что требует определенного времени.


6.5. Увеличение фрагментов диаграмм

Из книги Первые шаги с Windows 7. Руководство для начинающих автора Колисниченко Денис Н.

6.5. Увеличение фрагментов диаграмм С одним из методов создания в PROBE увеличенных фрагментов диаграмм вы уже познакомились: с помощью окон X Axis Settings и Y Axis Settings вы можете увеличить любой интересующий вас фрагмент до размеров всей рабочей поверхности экрана. Помимо этого, в


6.5. Увеличение производительности NTFS

Из книги Инфобизнес на полную мощность [Удвоение продаж] автора Парабеллум Андрей Алексеевич

6.5. Увеличение производительности NTFS Можно долго спорить о том, какая файловая система лучше — FAT32 или NTFS. С моей точки зрения — однозначно NTFS. Она обеспечивает должный уровень безопасности и предоставляет возможности, которые не доступны в FAT32, кроме того, она


Увеличение цены

Из книги AutoCAD 2009. Учебный курс автора Соколова Татьяна Юрьевна


Увеличение ценности

Из книги AutoCAD 2008 для студента: популярный самоучитель автора Соколова Татьяна Юрьевна


Увеличение объектов

Из книги Adobe Flash. Создание аркад, головоломок и других игр с помощью ActionScript автора Розенцвейг Гэри

Увеличение объектов Команда LENGTHEN , которая осуществляет увеличение объектов, вызывается из падающего меню Modify ? Lengthen.Действие команды LENGTHEN не распространяется на замкнутые объекты.Запросы команды


Увеличение объектов

Из книги автора

Увеличение объектов Команда LENGTHEN, которая осуществляет увеличение объектов, вызывается из падающего меню Modify ? Lengthen.Действие команды LENGTHEN не распространяется на замкнутые объекты.Запросы команды lengthen: Select an object or [DElta/Percent/Total/DYnamic]: – выбрать объект или один из ключейCurrent


Увеличение кнопок

Из книги автора

Увеличение кнопок Исходный файл: Expandingbuttons.fla Многие сайты используют Flash для навигации от страницы к странице. Даже простой Flash-ролик с одной кнопкой может значительно оживить статическую Web-страницу. При помощи ActionScript вы сможете сделать эти кнопки анимированными.Задача