- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания UNIX: взаимодействие процессов - Уильям Стивенс
Шрифт:
Интервал:
Закладка:
Опишем теперь работу функции semop в зависимости от трех возможных значений поля sem_op: отрицательного, нулевого и положительного.
1. Если значение sem_op положительно, оно добавляется к semval. Такое действие соответствует освобождению ресурсов, управляемых семафором. Если указан флаг SEM_UNDO, значение sem_op вычитается из значения semadj данного семафора.
2. Если значение semop равно нулю, вызвавший поток блокируется до тех пор, пока значение семафора (semval) не станет равным нулю. Если semval уже равно 0, происходит немедленное возвращение из функции.
Если semval не равно нулю, то ядро увеличивает значение поля semzcnt данного семафора и вызвавший поток блокируется до тех пор, пока значение semval не станет нулевым (после чего значение semzcnt будет уменьшено на 1). Как отмечалось ранее, поток будет приостановлен, только если не указан флаг IPC_NOWAIT. Если семафор будет удален в процессе ожидания либо будет перехвачен сигнал, произойдет преждевременный возврат из функции с возвращением кода ошибки.
3. Если значение sem_op отрицательно, вызвавший поток блокируется до тех пор, пока значение семафора не станет большим либо равным модулю sem_op. Это соответствует запрашиванию ресурсов.
Если значение semval больше либо равно модулю sem_op, модуль sem_op вычитается из semval. Если указан флаг SEM_UNDO, модуль sem_op добавляется к значению поля semadj данного семафора.
Если значение semval меньше модуля sem_op, значение поля semncnt данного семафора увеличивается, а вызвавший поток блокируется до тех пор, пока semval не станет больше либо равно модулю semop. Когда это произойдет, поток будет разблокирован, а модуль sem_op будет отнят от semval и из значения semncnt будет вычтена единица. Если указан флаг SEM_UNDO, модуль sem_op добавляется к значению поля semadj данного семафора. Как отмечалось ранее, поток не будет приостановлен, если указан флаг IPC_NOWAIT. Ожидание завершается преждевременно, если перехватываемый сигнал вызывает прерывание либо семафор удаляется другим потоком.
ПРИМЕЧАНИЕ
Если сравнить этот набор операций с теми, которые разрешены для семафоров Posix, мы увидим, что для последних определены только команды –1 (sem_wait) и +1 (sem_post). Для семафоров System V значение семафора может изменяться с шагом, отличным от 1, и кроме того, поток может ожидать, чтобы значение семафора стало нулевым. Эти операции являются более общими, что вместе с возможностью включения нескольких семафоров в набор делает семафоры System V более сложными, чем одиночные семафоры Posix.
11.4. Функция semctl
Функция semctl предназначена для выполнения разного рода вспомогательных управляющих операций с семафорами.
#include <sys/sem.h>
int semctl(int semid, int semnum, int cmd, …/* union semun arg */);
/* Возвращает неотрицательное значение в случае успешного завершения (см. в тексте). –1 – в случае ошибки */
Первый аргумент (semid) представляет собой идентификатор семафора, a semnum указывает элемент набора семафоров (0, 1 и т. д. до nsems –1). Значение semnum используется только командами GETVAL, SETVAL, GETNCNT, GETZCNT и GETPID.
Четвертый аргумент является дополнительным — он добавляется в зависимости от команды cmd (см. комментарии в описании объединения). Объявляется это объединение следующим образом:
union semun {
int val; /* используется только командой SETVAL */
struct semid_ds *buf; /* используется командами IPC_SET и IPC_STAT */
ushort *array; /* используется командами GETALL и SETALL */
};
Это объединение отсутствует в системных заголовочных файлах и должно декларироваться приложением (мы определяем его в заголовочном файле unpipc.h, листинг B.1). Оно передается по значению, а не по ссылке, то есть аргументом является собственно значение объединения, а не указатель на него.
ПРИМЕЧАНИЕ
К сожалению, в некоторых системах (FreeBSD и Linux) это объединение определено в заголовочном файле <sys/sem.h>, что затрудняет написание переносимых программ. Хотя в объявлении этого объединения в системном заголовочном файле и есть некоторый смысл, стандарт Unix 98 требует, чтобы оно каждый раз явно объявлялось приложением.
Ниже приведен список поддерживаемых значений аргумента cmd. В случае успешного завершения функция возвращает 0, а в случае ошибки – –1, если в описании команды не сказано что-либо другое.
■ GETVAL — возвращает текущее значение semval. Поскольку значение семафора отрицательным быть не может (semval объявляется как unsigned short — беззнаковое короткое целое), в случае успешного возврата значение всегда будет неотрицательным.
■ SETVAL — установка значения semval равным arg.val. В случае успешного выполнения корректировочное значение этого семафора (semadj) устанавливается равным нулю для всех процессов.
■ GETPID — функция возвращает текущее значение поля sempid.
■ GETNCNT — функция возвращает текущее значение поля semncnt.
■ GETZCNT — функция возвращает текущее значение поля semzcnt.
■ GETALL — возвращаются значения semval для всех элементов набора. Значения возвращаются через указатель arg.array, а сама функция при этом возвращает 0. Обратите внимание, что вызывающий процесс должен самостоятельно выделить массив беззнаковых коротких целых достаточного объема для хранения всех значений семафоров набора, а затем сделать так, чтобы arg.array указывал на этот массив.
■ SETALL — установка значений semval для всех элементов набора. Значения задаются через указатель arg.array.
■ IPC_RMID — удаление набора семафоров, задаваемого через идентификатор semid.
■ IPC_SET — установка трех полей структуры semid_ds равными соответствующим полям структуры arg.buf: sem_perm.uid, sem_perm.gid и sem_perm.mode. Поле sem_ctime структуры semid_ds устанавливается равным текущему времени.
■ IPC_STAT — возвращение вызвавшему процессу через аргумент arg.buf текущего значения полей структуры semid_ds для данного набора семафоров. Обратите внимание, что вызывающий процесс должен сначала выделить место под структуру semid_ds и установить на нее указатель arg.buf.
11.5. Простые программы
Поскольку семафоры System V обладают живучестью ядра, мы можем продемонстрировать работу с ними, написав несколько небольших программ, которые будут выполнять с семафорами различные действия. В промежутках между выполнением отдельных программ значения семафоров будут храниться в ядре.
Программа semcreate
Первая программа, текст которой приведен в листинге 11.1,[1] просто создает набор семафоров System V. Параметр командной строки –е соответствует флагу IPC_EXCL при вызове semget, а последним аргументом командной строки является количество семафоров в создаваемом наборе.
Листинг 11.1. Программа semcreate//svsem/semcreate.с
1 #include "unpipc.h"
2 int
3 main(int argc, char **argv)
4 {
5 int с, oflag, semid, nsems;
6 oflag = SVSEM_MODE | IPC_CREAT;
7 while ((c = Getopt(argc, argv, "e")) != –1) {
8 switch (c) {
9 case 'e':
10 oflag |= IPC_EXCL;
11 break;
12 }
13 }
14 if (optind != argc – 2)
15 err_quit("usage: semcreate [ –e ] <pathname> <nsems>");
16 nsems = atoi(argv[optind + 1]);
17 semid = Semget(Ftok(argv[optind], 0), nsems, oflag);
18 exit(0);
19 }
Программа semrmid
Следующая программа, текст которой приведен в листинге 11.2, удаляет набор семафоров из системы. Для этого используется вызов semctl с командой (аргументом cmd) IPC_RMID.
Листинг 11.2. Программа semrmid//svsem/semrmid.c
1 #include "unpipc.h"
2 int
3 main(int argc, char **argv)
4 {
5 int semid;
6 if (argc != 2)
7 err_quit("usage: semrmid <pathname>"):
8 semid = Semget(Ftok(argv[1], 0), 0, 0);
9 Semctl(semid, 0, IPC_RMID);
10 exit(0);
11 }
Программа semsetvalues
Программа semsetvalues (листинг 11.3) устанавливает значения всех семафоров набора.
Получение количества семафоров в наборе11-15 После получения идентификатора семафора с помощью semget мы вызываем semctl с командой IPC_STAT, чтобы получить значения полей структуры semid_ds для данного семафора. Поле sem_nsems содержит нужную нам информацию о количестве семафоров в наборе.
Установка всех значений19-24 Мы выделяем память под массив беззнаковых коротких целых, по одному элементу на каждый семафор набора, затем копируем полученные из командной строки значения в этот массив. Вызов semctl с командой SETALL позволяет установить все значения семафоров набора одновременно.
Листинг 11.3. Программа semsetvalues//svsem/semsetvalues.с