Руководство программиста для Linux


Разделяемая память - часть 3


Отметьте явное использование 0660 для прав доступа. Эта небольшая функция выдает либо идентификатор разделяемого сегмента памяти (int), либо -1 в случае ошибки. Значение ключа и заказанные размеры сегмента (в байтах) передаются в виде аргументов.

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

Системный вызов shmat() SYSTEM CALL: shmat(); PROTOTYPE: int shmat ( int shmid, char *shmaddr, int shmflg ); RETURNS: адрес, по которому сегмент был привязан к процессу, в случае успеха -1 в случае ошибки: errno = EINVAL (Ошибочно значение IPC ID или адрес привязки) ENOMEM (Недостаточно памяти для привязки сегмента) EACCES (Права отклонены) NOTES:

Если аргумент addr является нулем, ядро пытается найти нераспределенную область. Это рекомендуемый метод. Адрес может быть указан, но типично это используется только для облегчения работы аппаратного обеспечения или для разрешения конфликтов с другими приложениями. Флаг SHM_RND может быть OR-нут в аргумент флага, чтобы заставить переданный адрес выровняться по странице (округление до ближайшей страницы).

Кроме того, если устанавливается флаг SHM_RDONLY, то разделяемый сегмент памяти будет распределен, но помечен readonly.

Этот вызов, пожалуй, наиболее прост в использовании. Рассмотрим функцию-переходник, которая по корректному идентификатору сегмента возвращает адрес привязки сегмента: char *attach_segment( int shmid ) { return(shmat(shmid, 0, 0)); }

Если сегмент был правильно привязан, и процесс имеет указатель на начало сегмента, чтение и запись в сегмент становятся настолько же легкими,как манипуляции с указателями. Не потеряйте полученное значение указателя! Иначе у вас не будет способа найти базу (начало) сегмента. Системный вызов shmctl() SYSTEM SALL: shmctl(); PROTOTYPE: int shmctl ( int shmqid, int cmd, struct shmid_ds *buf ); RETURNS: 0 в случае успеха -1 в случае ошибки: errno = EACCESS (Нет прав на чтение при cmd, равном IPC_STAT) EFAULT (Адрес, на который указывает буфер, ошибочен при cmd, равном IPC_SET или IPC_STAT) EIDRM (Сегмент был удален во время вызова) EINVAL (ошибочный shmqid) EPERM (попытка выполнить команду IPC_SET или IPC_RMID но вызывающий процесс не имеет прав на запись (измените права доступа)) NOTES:




Начало  Назад  Вперед



Книжный магазин