Scroll to navigation

SHMCTL(2) Руководство программиста Linux SHMCTL(2)

ИМЯ

shmctl - управление общей памятью System V

СИНТАКСИС

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

int shmctl(int shmid, int cmd, struct shmid_ds *buf);

ОПИСАНИЕ

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

В аргументе buf содержится указатель на структуру shmid_ds, определённую в <sys/shm.h> следующим образом:


struct shmid_ds {

struct ipc_perm shm_perm; /* Ownership and permissions */
size_t shm_segsz; /* Size of segment (bytes) */
time_t shm_atime; /* Last attach time */
time_t shm_dtime; /* Last detach time */
time_t shm_ctime; /* Creation time/time of last
modification via shmctl() */
pid_t shm_cpid; /* PID of creator */
pid_t shm_lpid; /* PID of last shmat(2)/shmdt(2) */
shmatt_t shm_nattch; /* No. of current attaches */
... };

The fields of the shmid_ds structure are as follows:

This is an ipc_perm structure (see below) that specifies the access permissions on the shared memory segment.
Размер в байтах сегмента общей памяти.
Time of the last shmat(2) system call that attached this segment.
Time of the last shmdt(2) system call that detached tgis segment.
Time of creation of segment or time of the last shmctl() IPC_SET operation.
ID процесса, создавшего сегмент общей памяти.
ID of the last process that executed a shmat(2) or shmdt(2) system call on this segment.
Number of processes that have this segment attached.

Структура ipc_perm определена следующим образом (значения полей устанавливаются с помощью IPC_SET):


struct ipc_perm {

key_t __key; /* ключ, передаваемый в shmget(2) */
uid_t uid; /* эффективный UID владельца */
gid_t gid; /* эффективный GID владельца */
uid_t cuid; /* эффективный UID создателя */
gid_t cgid; /* эффективный GID создателя */
unsigned short mode; /* права + флаги SHM_DEST и
SHM_LOCKED */
unsigned short __seq; /* порядковый номер */ };

The least significant 9 bits of the mode field of the ipc_perm structure define the access permissions for the shared memory segment. The permission bits are as follows:

0400 Read by user
0200 Write by user
0040 Read by group
0020 Write by group
0004 Read by others
0002 Write by others

Bits 0100, 0010, and 0001 (the execute bits) are unused by the system. (It is not necessary to have execute permission on a segment in order to perform a shmat(2) call with the SHM_EXEC flag.)

Возможные значения cmd:

Копирует информацию из структуры данных ядра, связанной с shmid, в структуру shsid_ds, расположенную по адресу buf. Вызывающий должен иметь права на чтение общего сегмента памяти.
Write the values of some members of the shmid_ds structure pointed to by buf to the kernel data structure associated with this shared memory segment, updating also its shm_ctime member.
The following fields are updated: shm_perm.uid, shm_perm.gid, and (the least significant 9 bits of) shm_perm.mode.
The effective UID of the calling process must match the owner (shm_perm.uid) or creator (shm_perm.cuid) of the shared memory segment, or the caller must be privileged.
Помечает сегмент как удалённый. Сегмент будет удалён только после того как от него отключится последний процесс (т.е. когда поле shm_nattch из связанной структуры shmid_ds станет равно нулю). Вызывающий должен быть владельцем, создателем или иметь соответствующие привилегии. Аргумент buf игнорируется.
Если сегмент помечен на удаление, то в поле shm_perm.mode устанавливается (нестандартный) флаг SHM_DEST в связанной структуре данных, которая возвращается при операции IPC_STAT.
Вызывающий должен удостовериться, что сегмент в конечном итоге удалён; иначе ошибочные страницы останутся в памяти или в пространстве подкачки.
Смотрите также описание /proc/sys/kernel/shm_rmid_forced в proc(5).
Возвращает параметры и информацию о системных максимальных значениях общей памяти в структуре, указанной в buf. Данная структура имеет тип shminfo (то есть, требуется приведение типов) и определена в <sys/shm.h>, если определён макрос тестирования свойств _GNU_SOURCE:

struct shminfo {

unsigned long shmmax; /* максимальный размер
сегмента */
unsigned long shmmin; /* минимальный размер сегмента;
всегда 1 */
unsigned long shmmni; /* максимальное количество
сегментов */
unsigned long shmseg; /* максимальное количество
сегментов, к которому может
подключиться; процесс
не используется в ядре */
unsigned long shmall; /* макс. количество страниц
общей памяти в системе */ };

Значения shmmni, shmmax и shmall можно изменить с помощью файлов в /proc с теми же именами; подробней см. proc(5).
Возвращает структуру shm_info, чьи поля содержат информацию о системных ресурсах, использованных общей памятью. Эта структура определена в <sys/shm.h>, если определён макрос тестирования свойств _GNU_SOURCE:

struct shm_info {

int used_ids; /* количество используемых в
данный момент сегментов */
unsigned long shm_tot; /* общее количество общих
страниц памяти */
unsigned long shm_rss; /* количество общих страниц,
находящихся в памяти */
unsigned long shm_swp; /* количество страниц памяти в
пространстве подкачки */
unsigned long swap_attempts; /* не используется,
начиная с Linux 2.4 */
unsigned long swap_successes; /* не используется,
начиная с Linux 2.4 */ };

Возвращает структуру shmid_ds как в операции IPC_STAT. Однако аргумент shmid является не идентификатором сегмента, а индексом во внутреннем массиве ядра, в котором содержится информации о всех общих сегментов памяти в системе.
Возвращает структуру shmid_ds как для SHM_STAT. Однако shm_perm.mode не проверяется на доступность чтения для shmid, что означает, что эту операцию может выполнять пользователь (как и любой пользователь, который может прочитать эту же информацию из /proc/sysvipc/shm).

Вызывающий может запретить или разрешить размещение общего сегмента памяти в пространство подкачки с помощью следующих значений cmd:

Запрещает подкачку общего сегмента памяти. После включения блокировки вызывающий должен считать сбойными все страницы, наличие которых требуется. Если сегмент заблокирован, то в поле shm_perm.mode устанавливается (нестандартный) флаг SHM_LOCKED в связанной структуре, которая возвращается при операции IPC_STAT.
Разблокирует сегмент, разрешая выполнение подкачки.

В ядрах до версии 2.6.10 только привилегированный процесс мог использовать SHM_LOCK и SHM_UNLOCK. Начиная с ядра версии 2.6.10 непривилегированный процесс может использовать эти операции, если его эффективный UID совпадает с UID владельца или создателя сегмента и (для SHM_LOCK) количество блокируемой памяти находится в пределах ресурса RLIMIT_MEMLOCK (см. setrlimit(2)).

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

При успешном выполнении операции IPC_INFO или SHM_INFO возвращается индекс самого последнего использованного элемента внутреннего массива ядра, в котором записывается информация о всех общих сегментах памяти (эта информация может быть использована в повторяющихся операциях SHM_STAT или SHM_STAT_ANY для получения информации о всех общих сегментах памяти системы). При успешном выполнении операции SHM_STAT возвращается идентификатор общего сегмента памяти, чей индекс был указан в shmid. При успешном выполнении других операций возвращается 0.

В случае ошибки возвращается -1 и значение errno устанавливается соответствующим образом.

ОШИБКИ

Указана операция IPC_STAT или SHM_STAT, но в shm_perm.mode не установлено право на чтение shmid, и вызывающий процесс не имеет мандата CAP_IPC_OWNER в пространстве имён пользователя, который управляет его пространством имён IPC.
Значение аргумента cmd равно IPC_SET или IPC_STAT, но адрес, указанный в buf, недоступен.
Значение shmid указывает на удалённый идентификатор.
Значение shmid содержит недопустимый идентификатор, или cmd содержит недопустимую команду. Или (для SHM_STAT или SHM_STAT_ANY) индекс shmid ссылается на элемент массива, который в данный момент не используется.
(в ядрах, начиная с 2.6.9) Указана операция SHM_LOCK и размер блокируемого сегмента таков, что общее количество байт, блокируемое общими сегментами памяти, превысило бы ограничение, установленное для действительного идентификатора пользователя вызывающего процесса. Этот лимит определён мягким ограничителем ресурса RLIMIT_MEMLOCK (см. setrlimit(2)).
Попытка выполнить IPC_STAT, но значения GID или UID слишком велики для помещения в структуру, на которую указывает buf.
Попытка выполнить IPC_SET или IPC_RMID, но эффективный пользовательский идентификатор вызывающего процесса не равен идентификатору создателя (shm_perm.cuid) или владельца (shm_perm.uid) и процесс не привилегированный (Linux: не имеет мандата CAP_SYS_ADMIN).
Или (в ядрах до 2.6.9) процесс не имеет привилегий (Linux: не имеет мандата CAP_IPC_LOCK) для выполнения SHM_LOCK или SHM_UNLOCK. Начиная с Linux 2.6.9 эта ошибка также возникает, если значение RLIMIT_MEMLOCK равно 0 и вызывающий не имеет привилегий.

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

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

ЗАМЕЧАНИЯ

Включение файлов <sys/types.h> и <sys/ipc.h> не требуется в Linux или любых версий POSIX. Однако, некоторые старые реализации требуют включения данных заголовочных файлов, и это также требуется по SVID. В приложениях, которые нужно перенести на такие старые системы, может потребоваться включить данных заголовочные файлы.

The IPC_INFO, SHM_STAT, and SHM_INFO operations are used by the ipcs(1) program to provide information on allocated resources. In the future, these may modified or moved to a /proc filesystem interface.

Linux разрешает процессу подключаться (shmat(2)) к общему сегменту память, который уже помечен как удалённый с помощью shmctl(IPC_RMID). Это свойство недоступно в других реализациях UNIX; в переносимых приложениях лучше не использовать это свойство.

В Linux 2.2 различные поля struct shmid_ds имели тип short. В Linux 2.4 тип был изменён на long. Для задействования преимуществ этого изменения необходима перекомпиляция программы с glibc-2.1.91 или более поздней версией (ядро различает старые и новые вызовы по флагу IPC_64 в аргументе cmd).

СМ. ТАКЖЕ

mlock(2), setrlimit(2), shmget(2), shmop(2), capabilities(7), sysvipc(7)

ЗАМЕЧАНИЯ

Эта страница является частью проекта Linux man-pages версии 5.10. Описание проекта, информацию об ошибках и последнюю версию этой страницы можно найти по адресу https://www.kernel.org/doc/man-pages/.

ПЕРЕВОД

Русский перевод этой страницы руководства был сделан Alexander Golubev <fatzer2@gmail.com>, Azamat Hackimov <azamat.hackimov@gmail.com>, Hotellook, Nikita <zxcvbnm3230@mail.ru>, Spiros Georgaras <sng@hellug.gr>, Vladislav <ivladislavefimov@gmail.com>, Yuri Kozlov <yuray@komyakino.ru> и Иван Павлов <pavia00@gmail.com>

Этот перевод является бесплатной документацией; прочитайте Стандартную общественную лицензию GNU версии 3 или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.

Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное письмо на man-pages-ru-talks@lists.sourceforge.net.

21 декабря 2020 г. Linux