- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания UNIX: взаимодействие процессов - Уильям Стивенс
Шрифт:
Интервал:
Закладка:
Флаг oflag представляет собой комбинацию флагов доступа на чтение и запись из табл. 3.3. К ним могут быть добавлены с помощью логического сложения флаги IPC_CREAT или IPC_CREAT | IPC_EXCL, как уже говорилось в связи с рис. 3.2.
Новый сегмент инициализируется нулями.
Обратите внимание, что функция shmget создает или открывает сегмент разделяемой памяти, но не дает вызвавшему процессу доступа к нему. Для подключения сегмента памяти предназначена функция shmat, описанная в следующем разделе.
14.3. Функция shmat
После создания или открытия сегмента разделяемой памяти вызовом shmget его нужно подключить к адресному пространству процесса вызовом shmat:
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int flag);
/* Возвращает начальный адрес полученной области в случае успешного завершения. –1 –в случае ошибки */
Аргумент shmid — это идентификатор разделяемой памяти, возвращенный shmget. Функция shmat возвращает адрес начала области разделяемой памяти в адресном пространстве вызвавшего процесса. Правила, по которым формируется этот адрес, таковы:
■ если аргумент shmaddr представляет собой нулевой указатель, система сама выбирает начальный адрес для вызвавшего процесса. Это рекомендуемый (и обеспечивающий наилучшую совместимость) метод;
■ если shmaddr отличен от нуля, возвращаемый адрес зависит от того, был ли указан флаг SHM_RND (в аргументе flag ):
□ если флаг SHM_RND не указан, разделяемая память подключается непосредственно с адреса, указанного аргументом shmaddr,
□ если флаг SHM_RND указан, сегмент разделяемой памяти подключается с адреса, указанного аргументом shmaddr, округленного вниз до кратного константе SHMLBA. Аббревиатура LBA означает lower boundary address — нижний граничный адрес.
По умолчанию сегмент подключается для чтения и записи, если процесс обладает соответствующими разрешениями. В аргументе flag можно указать константу SHM_RDONLY, которая позволит установить доступ только на чтение.
14.4. Функция shmdt
После завершения работы с сегментом разделяемой памяти его следует отключить вызовом shmdt:
#include <sys/shm.h>
int shmdt(const void *shmaddr);
/* Возвращает 0 в случае успешного завершения, –1 – в случае ошибки */
При завершении работы процесса все сегменты, которые не были отключены им явно, отключаются автоматически.
Обратите внимание, что эта функция не удаляет сегмент разделяемой памяти. Удаление осуществляется функцией shmctl с командой IPC_RMIO.
14.5. Функция shmctl
Функция shmctl позволяет выполнять различные операции с сегментом разделяемой памяти:
#include <sys/shm.h>
int shmctl(int shmid, int and, struct shmid_ds *buff);
/* Возвращает 0 в случае успешного завершения, –1 в случае ошибки */
Команд (значений аргумента cmd) может быть три:
■ IPC_RMID — удаление сегмента разделяемой памяти с идентификатором shmid из системы;
■ IPC_SET — установка значений полей структуры shmid_ds для сегмента разделяемой памяти равными значениям соответствующих полей структуры, на которую указывает аргумент buff: shm_perm.uid, shm_perm.gid, shm_perm.mode. Значение поля shm_ctime устанавливается равным текущему системному времени;
■ IPC_STAT — возвращает вызывающему процессу (через аргумент buff) текущее значение структуры shmid_ds для указанного сегмента разделяемой памяти.
14.6. Простые программы
В этом разделе приведено несколько примеров простых программ, иллюстрирующих работу с разделяемой памятью System V.
Программа shmget
Программа shmget, текст которой приведен в листинге 14.1,[1] создает сегмент разделяемой памяти, принимая из командной строки полное имя и длину сегмента.
Листинг 14.1. Создание сегмента разделяемой памяти System V указанного размера//svshm/shmget.c
1 #include "unpipc.h"
2 int
3 main(int argc, char **argv)
4 {
5 int c, id, oflag;
6 char *ptr;
7 size_t length;
8 oflag = SVSHM_MODE | IPC_CREAT;
9 while ((c = Getopt(argc, argv, "e")) != –1) {
10 switch (c) {
11 case 'e':
12 oflag |= IPC_EXCL;
13 break;
14 }
15 }
16 if (optind != argc – 2)
17 err_quit("usage: shmget [ –e ] <pathname> <length>");
18 length = atoi(argv[optind + 1]);
19 id = Shmget(Ftok(argv[optind], 0), length, oflag);
20 ptr = Shmat(id, NULL, 0);
21 exit(0);
22 }
19 Вызов shmget создает сегмент разделяемой памяти указанного размера. Полное имя, передаваемое в качестве аргумента командной строки, преобразуется в ключ IPC System V вызовом ftok. Если указан параметр –е, наличие существующего сегмента с тем же именем приведет к возвращению ошибки. Если мы знаем, что сегмент уже существует, в командной строке должна быть указана нулевая длина.
20 Вызов shmat подключает сегмент к адресному пространству процесса. После этого программа завершает работу. Разделяемая память System V обладает поменьшей мере живучестью ядра, поэтому сегмент разделяемой памяти при этом не удаляется.
Программа shmrmid
В листинге 14.2 приведен текст тривиальной программы shmrmid, которая вызывает shmctl с командой IPC_RMID для удаления сегмента разделяемой памяти из системы.
Листинг 14.2. Удаление сегмента разделяемой памяти system V из системы//svshm/shmrmid.c
1 #include "unpipc.h"
2 int
3 main(int argc, char **argv)
4 {
5 int id;
6 if (argc != 2)
7 err_quit("usage: shmrmid <pathname>");
8 id = Shmget(Ftok(argv[1], 0), 0, SVSHM_MODE);
9 Shmctl(id, IPC_RMID, NULL);
10 exit(0);
11 }
Программа shmwrite
В листинге 14.3 приведен текст программы shmwrite, которая заполняет сегмент разделяемой памяти последовательностью значений 0, 1, 2, …, 254, 255, 0, 1 и т. д.
Листинг 14.3. Заполнение сегмента разделяемой памяти последовательностью чисел//svshm/shmwrite.c
1 #include "unpipc.h"
2 int
3 main(int argc, char **argv)
4 {
5 int i, id;
6 struct shmid_ds buff;
7 unsigned char *ptr;
8 if (argc != 2)
9 err_quit("usage: shmwrite <pathname>");
10 id = Shmget(Ftok(argv[1], 0), 0, SVSHM_MODE);
11 ptr = Shmat(id, NULL, 0);
12 Shmctl(id, IPC_STAT, &buff);
13 /* присваиваем: ptr[0] = 0, ptr[1] = 1 и т. д. */
14 for (i = 0; i < buff.shm_segsz; i++)
15 *ptr++ = i % 256;
16 exit(0);
17 }
10-12 Сегмент разделяемой памяти открывается вызовом shmget и подключается вызовом shmat. Его размер может быть получен вызовом shmctl с командой IPC_STAT.
13-15 В разделяемую память записывается последовательность значений.
Программа shmread
Программа shmread, текст которой приведен в листинге 14.4, проверяет последовательность значений, записанную в разделяемую память программой shmwrite.
Листинг 14.4. Проверка значений в сегменте разделяемой памяти//svshm/shmread.c
1 #include "unpipc.h"
2 int
3 main(int argc, char **argv)
4 {
5 int i, id;
6 struct shmid_ds buff;
7 unsigned char c, *ptr;
8 if (argc != 2)
9 err_quit("usage: shmread <pathname>");
10 id = Shmget(Ftok(argv[1], 0), 0, SVSHM_MODE);
11 ptr = Shmat(id, NULL, 0);
12 Shmctl(id, IPC_STAT, &buff);
13 /* проверка значений ptr[0] = 0, ptr[1] = 1 и т. д. */
14 for (i = 0; i < buff.shm_segsz; i++)
15 if ((c = *ptr++) != (i % 256))
16 err_ret("ptr[%d] = %d", i.e);
17 exit(0);
18 }
10-12 Открываем и подключаем сегмент разделяемой памяти. Его размер может быть получен вызовом shmctl с командой IPC_STAT. 13-16 Проверяется последовательность, записанная программой shmwrite.
Примеры
Создадим сегмент разделяемой памяти длиной 1234 байта в системе Solaris 2.6. Для идентификации сегмента используем полное имя нашего исполняемого файла shmget. Это имя будет передано функции ftok. Имя исполняемого файла сервера часто используется в качестве уникального идентификатора для данного приложения:
solaris % shmget shmget 1234
solaris % ipcs –bmo
IPC status from <running system> as of Thu Jan 8 13:17:06 1998
T ID KEY MODE OWNER GROUP NATTCH SEGSZ
Shared Memory:
m 1 0x0000f12a –rw-r--r-- rstevens other1 0 1234