Linux: Полное руководство
Шрифт:
♦ ENOMEM — не хватает памяти для создания сегмента.
Приведем пример функции открытия/создания РСП:
После получения идентификатора РСП мы должны «привязаться» к этому сегменту, то есть разместить сегмент в своем адресном пространстве. Для этого используется системный вызов shmat (shared memory attachment):
Первый аргумент — это идентификатор РСП, который мы получаем с помощью предыдущего вызова. Второй аргумент — это адрес привязки. Если указать вместо адреса ноль, то ядро само найдет нераспределенную область.
Третий аргумент — это флаги. Обычно используется два флага:
♦ SHM_RND — переданный адрес будет округлен до ближайшей страницы (если вы сами указываете адрес);
♦ SHM_RDONLY — РСП будет доступен только для чтения.
В случае успеха shmat возвращает адрес, по которому сегмент был привязан к процессу, или -1, если произошла ошибка. Переменная errno может принимать всего три значения:
♦ EACCESS — нет доступа;
♦ ENOMEM — не хватает памяти;
♦ EINVAL — ошибка в параметрах, то есть неправильное значение ID или адреса привязки (shmaddr).
Пример привязки:
После привязки сегмента к адресному пространству доступны операции чтения и записи, которые очень напоминают работу с простыми указателями.
Для снятия привязки используется системный вызов shmdt:
В случае ошибки данный системный вызов возвращает -1. Значение errno только одно: EINVAL, то есть вы неправильно указали адрес привязки. После отвязки значение элемента shm_nattch структуры shmid_ds уменьшается на 1. Если больше нет привязок, то есть shm_nattch = 0, сегмент будет удален ядром.
Для управления РСП используется системный вызов shmctl:
Первый аргумент — это идентификатор РСП, второй — команда, а третий — буфер для команд IPC_STAT/IPC_SET. Команд для управления три:
♦ IPC_STAT — сохраняет структуру shmid_ds по адресу buf;
♦ IPC_SET — берет значение элемента ipc_perm структуры shmid_ds и устанавливает его для сегмента. Значение берется из buf;
♦ IPC_RMID — помечает сегмент для удаления, само удаление произойдет, как только последний процесс отвяжется от сегмента. Если сегмент помечен на удаление, ни один процесс не сможет привязаться к сегменту.
В случае успеха системный вызов shmctl возвращает 0 или -1, если произошла ошибка. Переменная errno устанавливается так:
♦ EACCESS — нет прав;
♦ EFAULT — ошибочный адрес buf;
♦ EIDRM — сегмент помечен на удаление;
♦ EINVAL — неправильный идентификатор сегмента.
Вот теперь мы готовы к написанию демонстрационной программы для работы с разделяемыми сегментами памяти.
Листинг 26.6. Демонстрационная программа shm_demo.c
Искатель 2
2. Валинор
Фантастика:
фэнтези
попаданцы
рпг
рейтинг книги
Газлайтер. Том 18
18. История Телепата
Фантастика:
попаданцы
аниме
фэнтези
рейтинг книги
Хозяин Стужи 8
8. Злой Лед
Фантастика:
аниме
фэнтези
попаданцы
рейтинг книги
Вечный. Книга I
1. Вечный
Фантастика:
боевая фантастика
попаданцы
рпг
рейтинг книги
По прозвищу Святой. Книга первая
1. Святой
Фантастика:
попаданцы
альтернативная история
рейтинг книги
Сердце Дракона. Том 9
9. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
рейтинг книги
Загадка башни
9. Игра не для слабых
Фантастика:
рпг
фэнтези
попаданцы
рейтинг книги
Сапер. Том II
2. Сапер
Фантастика:
альтернативная история
рейтинг книги
Три `Д` для миллиардера. Свадебный салон
Любовные романы:
современные любовные романы
короткие любовные романы
рейтинг книги
На границе империй. Том 10. Часть 9
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
рейтинг книги
Третий. Том 5
5. Отпуск
Фантастика:
космическая фантастика
фантастика: прочее
рейтинг книги
Хозяин Стужи 5
5. Злой Лед
Фантастика:
аниме
фэнтези
попаданцы
рейтинг книги
Сирийский рубеж
5. Рубеж
Фантастика:
попаданцы
альтернативная история
рейтинг книги
Возлюби болезнь свою
Научно-образовательная:
психология
рейтинг книги