Документация Engee

Общая память

Пакет InterProcessCommunication предоставляет два вида объектов общей памяти: именованные объекты общей памяти, которые идентифицируются по их имени, и сегменты общей памяти BSD (System V), которые идентифицируются по ключу.

Объекты общей памяти

Объекты общей памяти являются экземплярами IPC.SharedMemory. Объект общей памяти создается следующим образом при вызове:

SharedMemory(id, len; perms=0o600, volatile=true)

с идентификатором id и размером len (в байтах) выделяемой памяти. Идентификатор id может быть строкой, начинающейся с символа '/', для создания объекта общей памяти POSIX, или ключом IPC System V для создания сегмента общей памяти BSD System V. В последнем случае ключ может представлять собой IPC.PRIVATE для автоматического создания несуществующего сегмента общей памяти.

Используйте ключевое слово perms, чтобы указать предоставляемые права доступа. По умолчанию пользователю разрешено выполнять только чтение и запись.

Используйте ключевое слово volatile, чтобы указать, является ли общая память непостоянной. Если память является постоянной, она будет доступна до явного уничтожения или перезагрузки системы. По умолчанию общая память уничтожается, если она больше не используется.

Чтобы получить существующий объект общей памяти, вызовите следующее:

SharedMemory(id; readonly=false)

где id — это идентификатор общей памяти (строка, ключ IPC или идентификатор IPC System V сегмента общей памяти System V, возвращаемый ShmId). Ключевому слову readonly можно задать значение true, если требуется доступ только для чтения. Обратите внимание, что для получения идентификатора объекта общей памяти obj можно вызвать метод shmid(obj).

Некоторые методы расширены для объектов общей памяти. Если предположить, что shm является экземпляром SharedMemory, то:

pointer(shm)    # выдает базовый адрес общей памяти
sizeof(shm)     # выдает количество байтов общей памяти
shmid(shm)      # выдает идентификатор общей памяти

Чтобы убедиться, что объект общей памяти shm в конце концов будет уничтожен, вызовите следующее:

rm(shm)

Общая память BSD System V

Следующие методы и типы предоставляют доступ более низкого уровня (по сравнению с объектами SharedMemory) для управления сегментами общей памяти BSD System V.

Идентификаторы сегментов общей памяти System V

Следующие операторы:

ShmId(id)                  -> id
ShmId(arr)                 -> id
ShmId(key, readlony=false) -> id

выдают идентификатор существующего сегмента общей памяти System V, связанного со значением первого аргумента. id является идентификатором сегмента общей памяти, arr — это массив, присоединенный к сегменту общей памяти System V, а key — ключ, связанный с сегментом общей памяти. В последнем случае readlony можно задать значение true, чтобы запрашивать доступ только для чтения. В противном случае будет запрашиваться доступ для чтения и записи.

Получает или создает сегмент общей памяти

Выполните следующее:

shmget(key, siz, flg) -> id

чтобы получить идентификатор сегмента общей памяти, связанного с ключом IPC System V key. Новый сегмент общей памяти, размер которого равен значению siz (возможно, округленному до кратного размера страницы памяти IPC.PAGE_SIZE), создается, если key имеет значение IPC.PRIVATE или если IPC_CREAT указан в аргументе flg, key не является IPC.PRIVATE и сегмент общей памяти, соответствующий key, не существует.

Аргумент flg представляет собой битовую комбинацию флагов. Наименее значимые 9 бит определяют разрешения, предоставленные владельцу, группе и другим. Эти биты имеют тот же формат и то же значение, что и аргумент mode chmod. Для создания нового сегмента можно задать бит IPC_CREAT. Если этот флаг не используется, shmget найдет сегмент, связанный с key, и проверит, есть ли у пользователя разрешение на доступ к этому сегменту. Бит IPC_EXCL можно задать дополнительно к IPC_CREAT, чтобы гарантировать, что этот вызов создаст сегмент. Если задан и IPC_EXCL, и IPC_CREAT, вызов завершится неудачей, если сегмент уже существует.

Присоединение и отсоединение общей памяти

Выполните следующее:

shmat(id, readonly) -> ptr

чтобы присоединить существующий сегмент общей памяти к адресному пространству вызывающего объекта. Аргумент id является идентификатором сегмента общей памяти. Логический аргумент readonly указывает, следует ли присоединять сегмент для доступа только для чтения. В противном случае сегмент присоединяется для доступа для чтения и записи и процесс должен иметь разрешения на чтение и запись для сегмента. Возвращаемое значение представляет собой указатель на сегмент общей памяти в адресном пространстве вызывающего объекта.

Предполагая, что ptr — это указатель, возвращенный предыдущим вызовом shmat():

shmdt(ptr)

отсоединяет сегмент общей памяти System V от адресного пространства вызывающего объекта.

Уничтожение общей памяти

Чтобы удалить общую память, связанную с arg, вызовите следующее:

shmrm(arg)

Если arg является именем, соответствующая именованная общая память POSIX будет отсоединена. Если arg является ключом или идентификатором сегмента общей памяти BSD, сегмент помечается как подлежащий уничтожению. Аргумент arg также может быть объектом SharedMemory.

Можно также вызвать метод rm для удаления существующего сегмента или объекта общей памяти:

rm(SharedMemory, name)
rm(SharedMemory, key)
rm(id)
rm(shm)

где name идентифицирует объект общей памяти POSIX, key связан с сегментом общей памяти BSD, id является идентификатором сегмента общей памяти BSD, а shm является экземпляром SharedMemory.

Управление общей памятью

Чтобы изменить права доступа сегмента общей памяти IPC System V, вызовите следующее:

shmcfg(arg, perms) -> id

где perms задает битовые флаги с новыми разрешениями. Первым аргументом может быть идентификатор сегмента общей памяти, общий массив, присоединенный к сегменту общей памяти, или ключ IPC System V, связанный с сегментом общей памяти. Во всех случаях возвращается идентификатор сегмента общей памяти.

Другие операции управления могут быть выполнены с помощью следующего:

shmctl(id, cmd, buf)

где id — это идентификатор сегмента общей памяти, cmd — команда для выполнения, а buf — буфер, достаточно большой для хранения структуры C shmid_ds (IPC._sizeof_struct_shmid_ds байт).

Получение сведений об общей памяти

Чтобы получить сведения о сегменте общей памяти System V, вызовите одно из следующих:

shminfo(arg) -> info
ShmInfo(arg) -> info

где arg — это идентификатор сегмента общей памяти, общий массив, присоединенный к сегменту общей памяти, или ключ IPC System V, связанный с сегментом общей памяти. Результатом будет экземпляр ShmInfo.

Можно задать память для структуры ShmInfo:

shminfo!(arg, info) -> info

где info — это экземпляр ShmInfo, который перезаписывается сведениями об arg и возвращается.