Опубликован: 06.12.2004 | Доступ: свободный | Студентов: 1096 / 126 | Оценка: 4.76 / 4.29 | Длительность: 20:58:00
ISBN: 978-5-9556-0021-5
Лекция 5:

Объекты в памяти

< Лекция 4 || Лекция 5: 1234 || Лекция 6 >
Аннотация: Анализируются основные идеи и понятия, обслуживающие отображение объектов в адресное пространство процессов. Детально рассматриваются файлы, отображенные в память, объекты в разделяемой и типизированной памяти, а также средства удержания процессов в памяти.
Ключевые слова: объект, адресное пространство процесса, доступ, средство межпроцессного взаимодействия, обычный файл, объект в разделяемой памяти, типизированная память, целое число, страница памяти, длина, генерация сигнала, вид доступа к отображенным страницам, доступ на чтение, доступ на запись, доступ на выполнение, отображение объекта в адресное пространство процесса, файловый дескриптор, операции, функция, память, адрес, управляющие, значение, приложение, запись, POSIX, место, аргумент, байт, отмена отображения, стандартный вывод, заголовочный файл, файл, execl, средство синхронизации, длительность ожидания, синхронизация оперативной и долговременной памяти, целостность данных, синхронизированный ввод/вывод, асинхронная запись, синхронная запись, инициализация кэш данных, программа, СУБД, пространство, функция обработки сигнала, список, ПО, объект в типизированной памяти, пул памяти, порт, пул, динамическая, ПЗУ, отображение части пула, непрерывный участок типизированной памяти, открытие объекта в типизированной памяти, информация, поле, дескриптор, минимум, отображение, блок памяти, запрос, указатель, массив, адресное пространство, страничная виртуальная память, подкачка по запросу, физическая память, кэш, удержание страниц в физической памяти, трансляция логического адреса в физический , завершение процесса, отмена удержания, удержание в памяти страниц растущего стека, стек

Отображение объектов в адресное пространство процессов

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

Отображаться могут обычные файлы, а также объекты в разделяемой и типизированной памяти.

Реализация должна обеспечивать, чтобы отображению подвергалось целое число страниц памяти из адресного пространства процесса. Размер страницы является значением конфигурационной переменной PAGESIZE. Отображаемая часть объекта должна начинаться с границы страницы. Длина отображаемой части не обязана быть кратной странице.

Попытки доступа к отображенной памяти, лежащей за текущей границей объекта, приводят к генерации сигнала SIGBUS.

К отображенным страницам могут предоставляться различные виды доступа: на чтение, запись и/или выполнение. При попытке нарушить наложенные ограничения процессу доставляется сигнал SIGSEGV.

Отображение объектов в адресное пространство процессов осуществляется функцией mmap() (см. листинг 5.1).

#include <sys/mman.h>
void *mmap (void *addr, size_t len, 
    int prot, int flags, 
	int fildes, off_t off);
Листинг 5.1. Описание функции mmap().

Отображаемая часть объекта задается файловым дескриптором fildes, смещением off и длиной len. (Вот для чего, заметим в скобках, при открытии объекта в разделяемой памяти функцией shm_open() возвращается файловый дескриптор - чтобы передать его mmap() и отобразить объект в адресное пространство процесса, а вовсе не для того, чтобы применять к нему операции файлового ввода/вывода. В исторически сложившихся реализациях функция mmap() появилась как средство отображения в память обычных файлов, так что с расширением функциональности другие виды отображаемых объектов пришлось стричь под ту же гребенку.)

Значения аргументов addr, prot и flags задают характеристики отображения - рекомендуемый адрес в адресном пространстве процесса, запрашиваемые виды доступа к отображенным страницам и управляющие флаги.

Результатом функции mmap() служит выбранный реализацией адрес в адресном пространстве процесса, начиная с которого отображен заданный фрагмент объекта, или, в случае неудачи, значение MAP_FAILED. Если в аргументе flags установлен флаг MAP_FIXED, результирующий адрес должен совпадать со значением addr ; предполагается, что приложение располагает знаниями о целевой архитектуре, достаточными для точной спецификации отображения, что, впрочем, отрицательным образом сказывается на мобильности. Если флаг MAP_FIXED не установлен, а значение addr равно NULL, реализация имеет полную свободу в выборе результирующего адреса; подобную комбинацию следует рекомендовать как максимально мобильную.

В значении аргумента flags, помимо MAP_FIXED, могут быть установлены флаги MAP_SHARED (запись в отображенную память изменяет отображаемый объект со всеми вытекающими отсюда последствиями) или MAP_PRIVATE (изменения в отображенной памяти видны только записывающему процессу и не распространяются на отображаемый объект). Стандарт POSIX-2001 не специфицирует, имеет ли место обратная зависимость, то есть видны ли процессу, установившему флаг MAP_PRIVATE, изменения в отображаемом объекте.

Аргумент prot, определяющий разрешенные виды доступа к отображенным страницам, строится как комбинация флагов PROT_READ, PROT_WRITE и PROT_EXEC (разрешен доступ, соответственно, на чтение, запись и/или выполнение ). Альтернативный вариант - установить флаг PROT_NONE, запрещающий доступ к странице (из общих соображений выключатель всегда должен быть под рукой). Значение аргумента prot должно быть согласовано с флагами, указанными при открытии объекта и получении дескриптора fildes.

Стандарт POSIX-2001 предусматривает возможность динамической смены разрешенных видов доступа к отображенным страницам посредством вызова функции mprotect() (см. листинг 5.2).

#include <sys/mman.h>
int mprotect (void *addr, 
    size_t len, int prot);
Листинг 5.2. Описание функции mprotect().

Виды доступа меняются в соответствии со значением аргумента prot для всех страниц, пересекающихся с частью адресного пространства процесса, начинающейся со значения addr (которое должно указывать на границу страницы) и имеющей длину len байт.

Нормальным результатом функции mprotect() (и описываемых далее функций) служит нуль; в случае ошибки возвращается -1.

Для отмены отображений в адресное пространство процессов служит функция munmap() (см. листинг 5.3).

#include <sys/mman.h>
int munmap (void *addr, size_t len);
Листинг 5.3. Описание функции munmap().

Отображения отменяются для страниц, пересекающихся с частью адресного пространства процесса, начинающейся со значения addr (которое должно указывать на границу страницы) и имеющей длину len байт.

Отображение объектов в адресное пространство процессов - универсальное, исключительно мощное средств. В качестве примера применим его для реализации упрощенного аналога служебной программы cat (см. листинг 5.4).

/* * * * * * * * * * * * * * * * * * * * * * * */
/* Программа выдает на стандартный вывод файлы,*/
/* имена которых заданы в командной строке     */
/* * * * * * * * * * * * * * * * * * * * * * * */

#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>

int main (int argc, char *argv []) {
	struct stat sbuf;  /* Структура для получения информации */
	                   /* о файле                            */
	int fd;            /* Дескриптор обрабатываемого файла   */
	void *maddr;       /* Адрес отображенного в память файла */
	int i;

	for (i = 1; i < argc; i++) {
		if ((fd = open (argv [i], O_RDONLY)) < 0) {
			perror ("OPEN");
			continue;
		}
		if (fstat (fd, &sbuf) != 0) {
			perror ("FSTAT");
			close (fd);
			continue;
		}
		if ((maddr = mmap (NULL, sbuf.st_size, 
			  PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED){
			perror ("MMAP");
			close (fd);
			continue;
		}
		if (write (STDOUT_FILENO, maddr, 
				sbuf.st_size) != sbuf.st_size) {
			perror ("WRITE");
		}
		if (munmap (maddr, sbuf.st_size) != 0) {
			perror ("MUNMAP");
		}
		close (fd);
	} /* for */

	return 0;
}
Листинг 5.4. Пример программы, использующей файлы, отображенные в память.

Отметим, что обрабатываемые файлы только открываются, но не читаются, а отображаются в память, откуда и выдаются на стандартный вывод. Роль буфера играют отображенные страницы.

< Лекция 4 || Лекция 5: 1234 || Лекция 6 >
Артем Хмелев
Артем Хмелев
Россия, 5
Mirzohid Abduhalilov
Mirzohid Abduhalilov
Узбекистан, Andijon