Главная » 2017 » Ноябрь » 24 » man 2 shmat
05:22
man 2 shmat

SEO sprint - Всё для максимальной раскрутки!





ИМЯ


shmat, shmdt - операции с общей памятью System V



ОБЗОР


#include <sys/types.h>
#include <sys/shm.h>

void *shmat(int shmid, const void *shmaddr, int shmflg);

int shmdt(const void *shmaddr);



ОПИСАНИЕ


shmat()
Вызов shmat() подключает сегмент общей памяти System V с идентификатором shmid к адресному
пространству вызывающего процесса. Адрес подключения, указанный в shmaddr, учитывается
следующим образом:

* Если значение shmaddr равно NULL, то система выбирает подходящий (неиспользуемый)
выровненный по странице адрес для подключения сегмента.

* Если значение shmaddr не равно NULL, а в shmflg указан флаг SHM_RND, то подключение
производится по адресу shmaddr, округлённому до ближайшего значения кратного SHMLBA.

* В противном случае shmaddr должно быть выровнено по адресу страницы, к которому
производится подключение.

В дополнении к SHM_RND, в аргументе битовой маски shmflg могут быть указаны следующие флаги:

SHM_EXEC (есть только в Linux; начиная с Linux 2.6.9)
Разрешить выполнение содержимого сегмента. Вызывающий должен иметь права на
выполнение сегмента.

SHM_RDONLY
Разрешить доступ к сегменту только для чтения. Процесс должен иметь права на чтение
сегмента. Если этот флаг не указан, то сегмент подключается с правом чтения и записи,
и процесс должен иметь права на чтение и запись сегмента. Об общих сегментах памяти,
доступных только на запись, ничего не упоминается.

SHM_REMAP (есть только в Linux)
Этот флаг указывает, что отображение сегмента должно замещать любые существующие
отображения в диапазоне, начиная с shmaddr и до размера сегмента (обычно выдается
ошибка EINVAL, если в этом диапазоне адресов уже есть отображение). В этом случае
значение shmaddr не должно быть равно NULL.

Значение brk(2) вызывающего процесса от подключения не изменяется. При завершении работы
процесса сегмент будет автоматически отсоединён. Один и тот же сегмент может быть подключён
в адресное пространство процесса несколько раз, как только для чтения, так и для
чтения-записи.

При успешном выполнении системный вызов shmat() обновляет поля структуры shmid_ds (см.
shmctl(2)), связанной с общим сегментом памяти, следующим образом:

Полю shm_atime присваивается значение текущего времени.

Значение shm_lpid устанавливается равным идентификатору вызывающего процесса.

Значение shm_nattch увеличивается на 1.
Полю shm_dtime присваивается значение текущего времени.

Значение shm_lpid устанавливается равным идентификатору вызывающего процесса.

Значение shm_nattch уменьшается на 1. Если оно становится равным 0 и сегмент помечен
для удаления, то сегмент удаляется.



ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ


При успешном выполнении shmat() возвращается адрес подключённого общего сегмента памяти; при
ошибке возвращается (void *) -1, а в errno содержится код ошибки.

При успешном выполнении shmdt() возвращается 0; при ошибке возвращается -1, а в errno
содержится код ошибки.



ОШИБКИ


Значения errno, устанавливаемые при возникновении ошибок в shmat():

EACCES Вызывающий процесс не имеет прав для подключения заданного типа и не имеет мандата
CAP_IPC_OWNER в пространстве имён пользователя, который управляет его пространством
имён IPC.

EIDRM Значение shmid указывает на удалённый идентификатор.

EINVAL Неправильное значение shmid, не выровненное (по границе страницы и не указан SHM_RND)
или неправильное значение shmaddr, или невозможно подключить сегмент по адресу
shmaddr, или был указан SHM_REMAP, но shmaddr равно NULL.

ENOMEM Невозможно выделить память для дескриптора или страничных таблиц.

Значения errno, устанавливаемые при возникновении ошибок в shmdt():

EINVAL По адресу shmaddr подключённый общий сегмент памяти отсутствует; или значение shmaddr
не выровнено по границе страницы.



СООТВЕТСТВИЕ СТАНДАРТАМ


POSIX.1-2001, POSIX.1-2008, SVr4.

В SVID 3 (возможно, чуть раньше) тип аргумента shmaddr изменён с char * на const void *, а
тип возвращаемого значения shmat() с char * на void *.



ЗАМЕЧАНИЯ


При вызове fork(2) потомки наследуют подключённые общие сегменты памяти.

При вызове execve(2) все подключённые общие сегменты памяти отключаются.

При вызове _exit(2) все подключённые общие сегменты памяти отключаются.

Для улучшения переносимости программ при подключении общего сегмента памяти рекомендуется
использовать shmat() с аргументом shmaddr, установленным в NULL. Необходимо учитывать, что
сегмент памяти, подключаемый таким способом, в разных процессах может подключаться по разным
адресам. Поэтому все указатели в области общей памяти должны быть не абсолютными, а
относительными (как правило относительно адреса начала сегмента).

В Linux сегмент общей памяти можно подключить даже, если он помечен для удаление. Однако в
POSIX.1 об этом ничего не сказано, и многие другие реализации это не поддерживают.

На работу shmat() влияют следующие системные параметры:
Реализацией не ограничивается количество общих сегментов общей памяти на процесс (SHMSEG).



СМОТРИТЕ ТАКЖЕ


brk(2), mmap(2), shmctl(2), shmget(2), capabilities(7), shm_overview(7), svipc(7)



Категория: (2) Системные вызовы ядра (функции языка Си) | Просмотров: 402 | Добавил: Администратор | Рейтинг: 0.0/0
Всего комментариев: 0
avatar