- Русские Блоги
- Несколько видов разделяемой памяти в Linux
- Использование общей памяти
- Отображение совместного использования памяти mmap
- Общая память XSI
- Общая память POSIX
- Изменить конфигурацию ядра с общей памятью
- Интеллектуальная рекомендация
- Используйте Maven для создания собственного архетипа скелета проекта (4)
- Станция интерпретации больших данных B пользуется популярностью среди гигантов района «призрачные животные» Цай Сюкуня.
- Вопрос A: Алгоритм 7-15: алгоритм кратчайшего пути Дейкстры
- Учебный дневник — перелистывание страниц
- Нулевое основание для отдыха-клиента
- Вам также может понравиться
- Подробно объясните, как новички используют sqlmap для выполнения инъекционных атак на базы данных mysql.
- Vue заметки сортируют, пусть вам начать с Vue.js:. 04_3 Сетевое приложение: AXIOS плюс Вью
- Шаблон алгоритма конной повозки
- 35 Line Code, чтобы получить метод исследования событий (ON)
- Образ докера: gitlab
- Средства System V IPC. Организация работы с разделяемой памятью в UNIX. Понятие нитей исполнения (thread)
- Разделяемая память в UNIX. Системные вызовы shmget(), shmat(), shmdt()
- Прогон программ с использованием разделяемой памяти
Русские Блоги
Несколько видов разделяемой памяти в Linux
Использование общей памяти
Есть много ограничений на использование файлов или каналов для межпроцессного взаимодействия. Каналы могут использоваться только между родительским процессом и дочерним процессом; из-за совместного использования файлов эффективность обработки ухудшается, а доступ к файловым дескрипторам не так удобен, как доступ к адресам памяти.
Система Linux предлагает три решения с общей памятью для программирования:
- Отображение совместного использования памяти mmap
- Общая память XSI
- Общая память POSIX
Отображение совместного использования памяти mmap
mmap изначально был функцией отображения памяти. Он может отображать файл в память и напрямую использовать адрес памяти для доступа к содержимому файла в программе.
Linux разделяет адресное пространство памяти между дочерним процессом и родительским процессом, полученным из системного вызова fork. Linux mmap реализует способ разделения адресов памяти между родительским и дочерним процессами.
- Родительский процесс устанавливает для параметра flags значение MAP_SHARED, чтобы применить к разделу памяти через mmap. Память может быть отображена в конкретный файл (fd) или нет (fd установлен в -1, флаг установлен в MAP_ANONYMOUS).
- Родительский процесс вызывает fork для порождения дочернего процесса, а затем адрес, возвращаемый mmap, может быть доступен в родительском и дочернем процессах, а память может использоваться совместно.
Использование этой разделяемой памяти обусловлено гонкой. Межпроцессное взаимодействие не только так же просто, как общение, но и позволяет иметь дело с аналогичными кодами критических секций. Здесь для обработки могут использоваться файловые блокировки. Однако использование файловых блокировок для разделяемой памяти не очень скоординировано. Помимо неудобств и неэффективности, блокировки файлов не позволяют выполнять более сложное управление процессами. Здесь семафоры, более сложный примитив управления синхронизацией процессов, могут использоваться для реализации связанных функций.
Следующая программа используется, чтобы помочь понять использование памяти mmap.
Подайте заявку на объем памяти почти 2 ГБ и установите для него значение 0. Наблюдайте за изменениями памяти.
Видно, что эта память была записана в разделяемую и буферную / кеш-память.
Одним из недостатков mmap является то, что разделяемая память может использоваться только между родительским процессом и дочерним процессом, порожденным fork, а другие процессы не могут получить адрес сегмента разделяемой памяти.
Общая память XSI
XSI — это набор стандартов интерфейса (X / Open System Interface), определенных организацией X / Open для UNIX. Реализация разделяемой памяти XSI в нижней части Linux существенно не отличается от mmap, за исключением метода использования.
Третий параметр shmget указывает флаг создания. Поддерживаемые флаги: IPC_CREAT, IPC_EXCL. Начиная с Linux 2.6, также была представлена разделяемая память, поддерживающая большие страницы, с пометкой: SHM_HUGETLB, SHM_HUGE_2MB и т. Д. Помимо создания новой общей памяти, shemget также может получить доступ к существующей памяти.В настоящее время вы можете установить для shmflg значение 0 и открыть его без каких-либо флагов.
Shmid типа int, возвращаемый shmget, похож на дескриптор файла. Обратите внимание, что это только похожая, а не та же реализация. Поэтому такие методы, как select, poll и epoll, не могут использоваться для управления общей памятью XSI. Для разделяемой памяти XSI ее ключ является глобально уникальным в системе, что удобно для других процессов, которые могут использовать тот же ключ для открытия того же раздела совместно используемой памяти для межпроцессного взаимодействия. Вместо этого дочерний процесс, сгенерированный fork, может напрямую обращаться к соответствующему сегменту разделяемой памяти через shmid. В этом суть ключа: глобальный уникальный идентификатор разделяемой памяти XSI в системе.
Ключ генерируется функцией ftok с использованием согласованного имени файла и proj_id. ftok не будет создавать файл, поэтому вы должны указать путь, который существует и доступен процессу. Кроме того, ftok не генерирует ключи на основе пути и имени файла файла. В конкретной реализации он использует номер inode указанного файла и номер устройства устройства, на котором находится файл. Следовательно, разные имена файлов также могут иметь один и тот же ключ (разные имена файлов указывают на один и тот же индекс, жесткую ссылку). Одно и то же имя файла не обязательно может иметь одинаковый ключ. Имя файла может быть удалено и перестроено. Такое поведение приведет к изменению inode.
В некоторых случаях также можно создать общую память без использования ключа. В это время вы можете заполнить IPC_PRIVATE в месте расположения ключевого параметра, чтобы ядро создавало новый раздел общей памяти без конфликтующего идентификатора сегмента общей памяти. Поскольку его можно только создать, бит флага должен иметь значение IPC_CREAT. Вы можете передать shmid дочернему процессу.
Когда получен shmid, shmat можно использовать для сопоставления адресов. После shmat доступ к сегменту разделяемой памяти можно получить, обратившись к возвращенному виртуальному адресу текущего процесса. Обратите внимание, что shmdt необходимо вызвать для отмены сопоставления после использования, иначе адрес виртуальной памяти может быть пропущен для длительно работающих программ. shmdt не может удалить сегмент общей памяти, а только удаляет взаимосвязь между сегментом общей памяти и виртуальным адресом процесса. Пока существует сегмент разделяемой памяти, соответствующий shmid, вы можете использовать shmat для продолжения сопоставления. Чтобы удалить сегмент общей памяти, вам необходимо использовать инструкцию shmctl IPC_RMID или использовать ipcrm в командной строке для удаления указанного идентификатора или ключа общей памяти.
shmctl также может просматривать и изменять связанные атрибуты общей памяти, которые можно просмотреть в man 2 shmctl. В системе вы также можете использовать команду ipcs -m для просмотра информации обо всей разделяемой памяти в системе.
В системе Linux при вызове shmget с использованием общей памяти XSI вы можете подать заявку на получение огромных страниц, установив параметр shmflg.
Преимущество использования большой страничной памяти заключается в повышении эффективности обработки ядра для управления памятью. Поскольку в случае того же объема памяти использование большой страничной памяти (2 МБ на страницу) значительно сократит количество операций управления страницами памяти, чем использование общих страниц памяти (4 КБ на страницу), тем самым уменьшив нагрузку на кеш для записей таблицы страниц памяти и кеш-памяти ЦП. Давление отображения адреса кэш-памяти. Но есть некоторые моменты, на которые следует обратить внимание:
- Память больших страниц не может быть заменена местами (SWAP)
- Неправильное использование может вызвать большие утечки памяти
- Для большой страничной памяти требуются права root
- Необходимо изменить конфигурацию системы
Если вы хотите подать заявку на большую страничную память ниже 2 ГБ, системе необходимо зарезервировать большую страничную память выше 2 ГБ.
2048 — это количество страниц, 2M на страницу.
Также нужно обратить внимание на ограничения разделяемой памяти:
/ proc / sys / kernel / shmall: ограничить общее количество страниц памяти, используемых системой в общей памяти. Страница обычно 4k (можно просмотреть через getconf PAGE_SIZE)
/ proc / sys / kernel / shmmax: ограничить максимальную длину сегмента разделяемой памяти в байтах.
/ proc / sys / kernel / shmmni: ограничить максимальное количество сегментов разделяемой памяти, которые может создать вся система.
Общая память POSIX
В общей памяти POSIX на самом деле нет ничего нового. По сути, это отображение mmap в совместное использование файлов, но оно отображает файлы в файловой системе tmpfs.
Tmpfs использует часть памяти в качестве файловой системы, которая обычно находится в каталоге / dev / shm.
Совместно используемая память POSIX, предоставляемая Linux, фактически создает файл в / dev / shm и сопоставляет его адрес памяти после mmap. Вы можете просмотреть использование через man shm_overview.
При компиляции этого кода вам необходимо указать библиотеку -lrt, которая является библиотекой Linux в реальном времени.
- Параметр SHMPATH в shm_open — это путь, который по умолчанию помещается в каталог / dev / shm системы. Это инкапсулируется shm_open, чтобы гарантировать, что файл должен находиться в tmpfs.
- Использование ftruncate для изменения размера разделяемой памяти фактически изменяет длину файла.
- shm_unlink на самом деле представляет собой пакет системных вызовов unlink. Если операция отмены связи не выполняется, файл всегда будет существовать в каталоге / dev / shm.
- Чтобы закрыть дескриптор разделяемой памяти, используйте close.
Изменить конфигурацию ядра с общей памятью
Максимальный размер (в байтах), который процесс может выделить для конца совместно используемой памяти в своем виртуальном адресном пространстве.
Количество сегментов разделяемой памяти в масштабе всей системы
Этот параметр устанавливает количество страниц, которые могут использоваться в общей памяти в рамках всей системы. Единица измерения — PAGE_SIZE (обычно 4096, можно передать getconf PAGE_SIZE получения).
выполненный ipcs -m Просмотреть всю разделяемую память в системе. в случае status Поле есть dest , Указывая на то, что эту общую память необходимо удалить.
Интеллектуальная рекомендация
Используйте Maven для создания собственного архетипа скелета проекта (4)
Один, базовое введение в Maven Во-вторых, скачайте и настройте Maven Три, настроить домашнее зеркало на Али В-четвертых, создайте содержимое скелета архетипа В-пятых, создайте проект через архетип 6. .
Станция интерпретации больших данных B пользуется популярностью среди гигантов района «призрачные животные» Цай Сюкуня.
Автор | Сюй Линь Ответственный редактор | Ху Вэйвэй Предисловие Недавно Цай Сюкунь отправил письмо юриста на станцию B. Содержание письма юриста показало, что «на станции B имеется большое кол.
Вопрос A: Алгоритм 7-15: алгоритм кратчайшего пути Дейкстры
Название Описание Во взвешенном ориентированном графе G для исходной точки v задача о кратчайшем пути от v до оставшихся вершин в G называется задачей кратчайшего пути с одной исходной точкой. Среди ш.
Учебный дневник — перелистывание страниц
Используйте плагин Layui.
Нулевое основание для отдыха-клиента
Предисловие: статья, обобщенная, когда я только что связался с тестом API, в дополнение к остальному клиенту этот инструмент сам, некоторые из мелких пониманий API, я надеюсь помочь тому же белую белу.
Вам также может понравиться
Подробно объясните, как новички используют sqlmap для выполнения инъекционных атак на базы данных mysql.
Шаг 1. Откройте для себя инъекцию Со мной все было нормально, когда я был свободен, я случайно нажал на чужой блог и обнаружил, что ссылка заканчивается на id, поэтому я проверил его вручную. Результа.
Vue заметки сортируют, пусть вам начать с Vue.js:. 04_3 Сетевое приложение: AXIOS плюс Вью
В предыдущем разделе мы ввели основное использование AXIOS, по сравнению с нативным Ajax, который при условии, что способ является более простым и, а сетевые данные теперь в состоянии получить его ров.
Шаблон алгоритма конной повозки
Блог гангстеров Тележки, запряженные лошадьми, используются для решения проблемы самой длинной подстроки палиндрома. Основное внимание уделяется подстрокам, а не подпоследовательностям. Если вы хотите.
35 Line Code, чтобы получить метод исследования событий (ON)
Об авторе: Чжу Сяою,Личный публичный номер: языковой класс большой кошки Эта проблема научит вас этой большой классе Cat.Как написать наиболее эффективное метод исследования событий с 35 Line R Code C.
Образ докера: gitlab
GitLab Docker images Both GitLab CE and EE are in Docker Hub: GitLab CE Docker image GitLab EE Docker image The GitLab Docker images are monolithic images of GitLab running all the necessary services .
Источник
Средства System V IPC. Организация работы с разделяемой памятью в UNIX. Понятие нитей исполнения (thread)
Разделяемая память в UNIX. Системные вызовы shmget(), shmat(), shmdt()
С точки зрения операционной системы, наименее семантически нагруженным средством System V IPC является разделяемая память (shared memory) . Мы уже упоминали об этой категории средств связи на лекции. Для текущего семинара нам достаточно знать, что операционная система может позволить нескольким процессам совместно использовать некоторую область адресного пространства. Внутренние механизмы , позволяющие реализовать такое использование, будут подробно рассмотрены на лекции, посвященной сегментной, страничной и сегментно-страничной организации памяти.
Все средства связи System V IPC требуют предварительных инициализирующих действий (создания) для организации взаимодействия процессов.
Для создания области разделяемой памяти с определенным ключом или доступа по ключу к уже существующей области применяется системный вызов shmget() . Существует два варианта его использования для создания новой области разделяемой памяти .
- Стандартный способ. В качестве значения ключа системному вызову поставляется значение, сформированное функцией ftok() для некоторого имени файла и номера экземпляра области разделяемой памяти . В качестве флагов поставляется комбинация прав доступа к создаваемому сегменту и флага IPC_CREAT . Если сегмент для данного ключа еще не существует, то система будет пытаться создать его с указанными правами доступа. Если же вдруг он уже существовал, то мы просто получим его дескриптор. Возможно добавление к этой комбинации флагов флага IPC_EXCL . Этот флаг гарантирует нормальное завершение системного вызова только в том случае, если сегмент действительно был создан (т. е. ранее он не существовал), если же сегмент существовал, то системный вызов завершится с ошибкой, и значение системной переменной errno , описанной в файле errno.h , будет установлено в EEXIST .
- Нестандартный способ. В качестве значения ключа указывается специальное значение IPC_PRIVATE . Использование значения IPC_PRIVATE всегда приводит к попытке создания нового сегмента разделяемой памяти с заданными правами доступа и с ключом, который не совпадает со значением ключа ни одного из уже существующих сегментов и который не может быть получен с помощью функции ftok() ни при одной комбинации ее параметров. Наличие флагов IPC_CREAT и IPC_EXCL в этом случае игнорируется.
Системный вызов shmget()
Прототип системного вызова
Описание системного вызова
Системный вызов shmget предназначен для выполнения операции доступа к сегменту разделяемой памяти и, в случае его успешного завершения, возвращает дескриптор System V IPC для этого сегмента (целое неотрицательное число, однозначно характеризующее сегмент внутри вычислительной системы и использующееся в дальнейшем для других операций с ним).
Параметр key является ключом System V IPC для сегмента, т. е. фактически его именем из пространства имен System V IPC . В качестве значения этого параметра может использоваться значение ключа, полученное с помощью функции ftok() , или специальное значение IPC_PRIVATE . Использование значения IPC_PRIVATE всегда приводит к попытке создания нового сегмента разделяемой памяти с ключом,который не совпадает со значением ключа ни одного из уже существующих сегментов и который не может быть получен с помощью функции ftok() ни при одной комбинации ее параметров.
Параметр size . определяет размер создаваемого или уже существующего сегмента в байтах. Если сегмент с указанным ключом уже существует, но его размер не совпадает с указанным в параметре size , констатируется возникновение ошибки.
Параметр shmflg – флаги – играет роль только при создании нового сегмента разделяемой памяти и определяет права различных пользователей при доступе к сегменту, а также необходимость создания нового сегмента и поведение системного вызова при попытке создания. Он является некоторой комбинацией (с помощью операции побитовое или – » | «) следующих предопределенных значений и восьмеричных прав доступа:
- IPC_CREAT – если сегмента для указанного ключа не существует, он должен быть создан;
- IPC_EXCL – применяется совместно с флагом IPC_CREAT . При совместном их использовании и существовании сегмента с указанным ключом, доступ к сегменту не производится и констатируется ошибочная ситуация, при этом переменная errno , описанная в файле , примет значение EEXIST ;
- 0400 – разрешено чтение для пользователя, создавшего сегмент;
- 0200 – разрешена запись для пользователя, создавшего сегмент;
- 0040 – разрешено чтение для группы пользователя, создавшего сегмент;
- 0020 – разрешена запись для группы пользователя, создавшего сегмент;
- 0004 – разрешено чтение для всех остальных пользователей;
- 0002 – разрешена запись для всех остальных пользователей.
Системный вызов возвращает значение дескриптора System V IPC для сегмента разделяемой памяти при нормальном завершении и значение -1 при возникновении ошибки.
Доступ к созданной области разделяемой памяти в дальнейшем обеспечивается ее дескриптором, который вернет системный вызов shmget() . Доступ к уже существующей области также может осуществляться двумя способами:
- Если мы знаем ее ключ, то, используя вызов shmget() ,можем получить ее дескриптор. В этом случае нельзя указывать в качестве составной части флагов флаг IPC_EXCL , а значение ключа, естественно, не может быть IPC_PRIVATE . Права доступа игнорируются, а размер области должен совпадать с размером, указанным при ее создании.
- Либо мы можем воспользоваться тем, что дескриптор System V IPC действителен в рамках всей операционной системы, и передать его значение от процесса, создавшего разделяемую память , текущему процессу. Отметим, что при создании разделяемой памяти с помощью значения IPC_PRIVATE – это единственно возможный способ.
После получения дескриптора необходимо включить область разделяемой памяти в адресное пространство текущего процесса. Это осуществляется с помощью системного вызова shmat() . При нормальном завершении он вернет адрес разделяемой памяти в адресном пространстве текущего процесса. Дальнейший доступ к этой памяти осуществляется с помощью обычных средств языка программирования.
Системный вызов shmat()
Прототип системного вызова
Описание системного вызова
Системный вызов shmat предназначен для включения области разделяемой памяти в адресное пространство текущего процесса. Данное описание не является полным описанием системного вызова, а ограничивается рамками текущего курса. Для полного описания обращайтесь к UNIX Manual.
Параметр shmid является дескриптором System V IPC для сегмента разделяемой памяти, т. е. значением, которое вернул системный вызов shmget() при создании сегмента или при его поиске по ключу.
В качестве параметра shmaddr в рамках нашего курса мы всегда будем передавать значение NULL , позволяя операционной системе самой разместить разделяемую память в адресном пространстве нашего процесса.
Параметр shmflg в нашем курсе может принимать только два значения: 0 – для осуществления операций чтения и записи над сегментом и SHM_RDONLY – если мы хотим только читать из него. При этом процесс должен иметь соответствующие права доступа к сегменту.
Системный вызов возвращает адрес сегмента разделяемой памяти в адресном пространстве процесса при нормальном завершении и значение -1 при возникновении ошибки.
После окончания использования разделяемой памяти процесс может уменьшить размер своего адресного пространства, исключив из него эту область с помощью системного вызова shmdt() . Отметим, что в качестве параметра системный вызов shmdt() требует адрес начала области разделяемой памяти в адресном пространстве процесса, т. е. значение , которое вернул системный вызов shmat() , поэтому данное значение следует сохранять на протяжении всего времени использования разделяемой памяти .
Системный вызов shmdt()
Прототип системного вызова
Описание системного вызова
Системный вызов shmdt предназначен для исключения области разделяемой памяти из адресного пространства текущего процесса.
Параметр shmaddr является адресом сегмента разделяемой памяти,т. е. значением, которое вернул системный вызов shmat() .
Системный вызов возвращает значение 0 при нормальном завершении и значение -1 при возникновении ошибки.
Прогон программ с использованием разделяемой памяти
Для иллюстрации использования разделяемой памяти давайте рассмотрим две взаимодействующие программы.
Эти программы очень похожи друг на друга и используют разделяемую память для хранения числа запусков каждой из программ и их суммы. В разделяемой памяти размещается массив из трех целых чисел. Первый элемент массива используется как счетчик для программы 1, второй элемент – для программы 2, третий элемент – для обеих программ суммарно. Дополнительный нюанс в программах возникает из-за необходимости инициализации элементов массива при создании разделяемой памяти . Для этого нам нужно, чтобы программы могли различать случай, когда они создали ее, и случай, когда она уже существовала. Мы добиваемся различия, используя вначале системный вызов shmget() с флагами IPC_CREAT и IPC_EXCL . Если вызов завершается нормально, то мы создали разделяемую память . Если вызов завершается с констатацией ошибки и значение переменной errno равняется EEXIST , то, значит, разделяемая память уже существует, и мы можем получить ее IPC дескриптор , применяя тот же самый вызов с нулевым значением флагов. Наберите программы, сохраните под именами 06-1а.с и 06-1b.c cоответственно, откомпилируйте их и запустите несколько раз. Проанализируйте полученные результаты.
Источник