- •Функционирование менеджера памяти
- •Содержание
- •Разделяемая память
- •Прогон программы, демонстрирующей передачу информации от одного процесса к другому через разделяемую память
- •Написание, компиляция и выполнение программы обмена информацией через разделяемый буфер памяти с использованием системной области выгрузки
- •Физическая память
- •Рабочие наборы процессов
- •Прогон программы, иллюстрирующей увеличение рабочего набора процесса
- •База данных pfn. Страничные демоны
- •Эксперимент. Наблюдение за ошибками страниц
- •Отдельные аспекты функционирования менеджера памяти
- •Локализация страниц в памяти
- •Прогон программы, демонстрирующей блокировку страниц в памяти
- •Копирование при записи
- •Прогон программы, иллюстрирующей отложенное выделение памяти
- •Контроль процессом памяти другого процесса
- •Написание, компиляция и выполнение программы, осуществляющей доступ к памяти дочернего процесса
- •Заключение
Разделяемая память
Как уже было сказано в предыдущей лекции, при отображении файла в память образуется регион в виртуальной памяти, а также сопутствующий ему объект-раздел или объект-секция (section object). Как и другие объекты, объекты-разделы управляются диспетчером объектов. В случае возникновения ошибок страниц подкачка осуществляется из страниц проецируемого файла, а не из общесистемного файла выгрузки.
Для таких регионов формируется массив прототипных PTE, описывающих нахождение всех страниц этого фрагмента памяти. PTE таблицы страниц процесса, выполнившего отображение, ссылаются на прототипные PTE, как это показано на рис. 10.4, и тоже считаются недействительными. Если при этом другой процесс выполнил отображение этого же файла, то PTE его таблицы тоже будут ссылаться на эти же самые прототипные PTE (см. рис. 10.4). Таким образом, физические страницы памяти будут обобществлены.
увеличить изображение Рис. 10.4. Реализация разделяемого между двумя процессами региона проецируемого в память файла
Изменения, сделанные в данном фрагменте памяти одним процессом, будут сразу же "видны" другому процессу. Таким образом, наличие таблицы прототипных PTE обеспечивает когерентность разделяемой памяти.
Более того, если третий процесс открыл тот же самый файл для обычного ввода-вывода, то уже существующее отображение будут рассматриваться в качестве буфера кэша этого файла, доступ к которому будет осуществляться через ту же самую таблицу прототипных PTE. Таким образом, все три процесса будут работать с одной и той же версией файла.
Помимо обмена информацией между различными процессами, разделяемые страницы применяются также для передачи данных между пользовательской и ядерной частями адресного пространства процесса. Примерами могут служить передача системной информации или передача информации от драйвера ввода-вывода.
Прогон программы, демонстрирующей передачу информации от одного процесса к другому через разделяемую память
Рассмотрим текст двух программ first.c и second.c
First.c
#include <windows.h>
#include <stdio.h>
void main(void){
HANDLE hMapFile;
LPVOID lpMapAddress;
HANDLE hFile;
char * String;
hFile = CreateFile("MyFile.txt", // имя файла
GENERIC_READ | GENERIC_WRITE, // файл для чтения и записи
FILE_SHARE_READ| FILE_SHARE_WRITE,// режим совместного доступа
NULL, // защита по умолчанию
OPEN_EXISTING, // файл должен существовать
FILE_ATTRIBUTE_NORMAL, // атрибуты файла
NULL); // файл атрибутов
if (hFile == INVALID_HANDLE_VALUE) printf("Could not open file\n");
hMapFile = CreateFileMapping(hFile, // описатель отображаемого файла
NULL, // атрибуты защиты по умолчанию
PAGE_READWRITE, // режим доступа
0, // старшее двойное слово размера буфера
0, // младшее двойное слово размера буфера
"MyFileObject"); // имя объекта
if (hMapFile == NULL) printf("Could not create file-mapping object.\n");
lpMapAddress = MapViewOfFile(hMapFile, // описатель отображаемого файла
FILE_MAP_ALL_ACCESS, // режимы доступа
0, 0, // отображение файла с начала
0); // отображение целого файла
if (lpMapAddress == NULL) printf("Could not map view of file.\n");
String = (char *)lpMapAddress;
sprintf(String, "Hello, world");
getchar();
}
Пример 10.1. (html, txt)
second.c
#include <windows.h>
#include <stdio.h>
void main(void){
HANDLE hMapFile;
LPVOID lpMapAddress;
HANDLE hFile;
char * String;
hFile = CreateFile("MyFile.txt", // имя файла
GENERIC_READ | GENERIC_WRITE, // файл для чтения и записи
FILE_SHARE_READ| FILE_SHARE_WRITE,// режим совместного доступа
NULL, // защита по умолчанию
OPEN_EXISTING, // файл должен существовать
FILE_ATTRIBUTE_NORMAL, // атрибуты файла
NULL); // файл атрибутов
if (hFile == INVALID_HANDLE_VALUE)
{
printf("Could not open file\n"); // process error
}
hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, // разрешение чтения-записи
FALSE, // описатель не наследуется
"MyFileObject"); // имя объекта проецируемого файла
if (hMapFile == NULL) printf("Could not open Filemapping\n");
lpMapAddress = MapViewOfFile(hMapFile, // описатель отображаемого файла
FILE_MAP_ALL_ACCESS, // режимы доступа
0, 0, // отображение файла с начала
0); // отображение целого файла
if (lpMapAddress == NULL) printf("Could not map view of file.\n");
String = (char *)lpMapAddress;
printf("%s\n", String);
getchar();
}
Пример 10.2. (html, txt)
Программа first создает в своем адресном пространстве буфер разделяемой памяти, а программа second отображает тот же самый буфер в свое адресное пространство. Затем программа first записывает в этот буфер текстовую строку, а программа second выводит ее содержимое на экран. Обе программы должны быть запущены из одного каталога с уже существующим файлом MyFile.txt. Для наглядности рекомендуется, чтобы длина файла была изначально больше длины строки "Hello, world".
