Применение технологии разделяемой памяти в межпроцессном взаимодействии компонентов операционных систем
Возникновение идеи разделяемой памяти. Ценность концепции для системного программирования. Принцип взаимодействия процессов через область разделяемой памяти. Отличия в разных операционных системах. Проблема безопасности при работе с разделяемой памятью.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | курсовая работа |
Язык | русский |
Дата добавления | 16.08.2009 |
Размер файла | 352,4 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Кафедра ИКТ
Курсовая работа по дисциплине
«Системное Программное Обеспечение»
На тему:
«Применение технологии разделяемой памяти в межпроцессном взаимодействии компонентов операционных систем»
Выполнила: Бобылева А.А.
Группа: С-84
Проверил: Зарудный Д. И.
Москва, 2008 г.
План
1. Аннотация
2. Постановка задачи
3. Предпосылки возникновения идеи разделяемой памяти. Ценность данной концепции для системного программирования.
4. Описание принципа взаимодействия процессов через область разделяемой памяти. Отличия в различных операционных системах.
5. Пример - исходный код на языке C для OS Unix.
6. Проблематика безопасности при работе с разделяемой памятью.
Заключение
Постановка задачи
Описать принцип взаимодействия процессов через разделяемую память. Проанализировать преимущества и недостатки такого подхода к обмену данными между процессами в различных операционных системах. Привести пример такого взаимодействия. Сделать выводы о применимости концепции разделяемой памяти в системном программировании.
Предпосылки возникновения идеи разделяемой памяти. Ценность данной концепции для системного программирования.
Традиционно адресное пространство каждого процесса было полностью изолировано от адресного пространства всех других процессов, работающих в системе. единственным исключением было разделение с доступом только для чтения кода программы. Все межпроцессное взаимодействие осуществлялось посредством хорошо определенных путей, которые проходили через ядро: каналы, сокеты, файлы и специальные устройства. Преимуществом этого изолированного подхода является то, что, независимо от каких бы то ни было разрушительных действий процесса в его собственном адресном пространстве, он не мог повлиять на адресное пространство других работающих в системе процессов. Каждый процесс может строго контролировать отправку и получение данных; он может также точно определять места внутри своего адресного пространства, которые читаются и записываются. Недостатком этого подхода является то, что все межпроцессные взаимодействия требуют по крайней мере двух системных вызовов: одного для отправляющего и одного для получающего процесса. Для больших объемов межпроцессного взаимодействия, особенно при частом обмене небольшими пакетами данных, в стоимости коммуникации преобладают издержки системных вызовов.
Разделяемая память представляет собой способ значительно снизить стоимость межпроцессной коммуникации. Два или более процессов, которые хотят взаимодействовать, отображают один и тот же участок читаемой-записываемой памяти свое адресное пространство. Когда все процессы отобразили память в свое адресное пространство, любые изменения этого участка памяти видны всем другим процессам без всякого вмешательства со стороны ядра. Таким образом, межпроцессное взаимодействие может быть достигнуто безо всяких издержек на системные вызовы, кроме стоимости первоначального отображения. Недостатком этоо подхода является то, что если процесс, отобразивший данные, повержит структуры данных в этой памяти, все другие процессы, отображающие эту память, также будут повреждены. Кроме того, перед разработчиком приложения возникает сложность относительно того, кто должен разрабатывать структуры данных для управления доступом к разделяемой памяти и справляться с условиями гонки (race condition), присущими манипулированию и управлению такими структурами данных, доступ к которым осуществляется параллельно.
В некоторых вариантах системы Unix есть механизм основанного на ядре семафора для предоставления необходимого упорядочивания доступа к разделяемой памяти. Однако, как получение, так и установка таких семафоров требуют системных вызовов. Издержки по использованию таких семафоров сравнимы с издержками использования традиционных методов межпроцессного взаимодействия. К сожалению, эти семафоры имеют всю сложность разделяемой памяти, давая к тому же весьма незначительный выигрыш в скорости. Главной причиной для введения сложности разделяемой памяти является соразмерное преимущество в скорости. Если должно быть получено это преимущество, большая часть потребностей в блокировке структур данных должна осуществляться в самом сегменте разделяемой памяти. Основанные на ядре семафоры должны использоваться лишь в тех редких случаях, когда имеется соперничество за блокировку и один процесс должен ждать. Поэтому современные интерфейсы, такие как POSIX Pthreads, спроектированы таким образом, что семафоры могут быть расположены в области разделяемой памяти. В общем случае установка или освобождение неоспариваемого семафора могут осуществляться процессом пользователя без вызова ядра. Имеются два случая, когда процесс обязан сделать системный вызов. Если процесс пытается вызвать заблокированный семафор, он должен вызвать ядро, чтобы заблокироваться и ждать, пока семафор станет доступным. Этот системный вызов мало влияет на производительность, поскольку блокировка оспаривается, поэтому невозможно продолжать работу и в любом случае должно быть вызвано ядро для переключения контекста. Если процесс освобождает семафор, который хочет получить другой процесс, он должен вызвать ядро, чтобы пробудить этот процесс. Поскольку большинство блокировок не оспариваются, приложения могут работать с полной скоростью без вмешательства ядра.
Таким образом, мы получаем быстрый и дешевый метод доступа процессов к общей памяти, крайне соблазнительный для применения в системном программировании.
Описание принципа взаимодействия процессов через область разделяемой памяти. Отличия в различных операционных системах.
В различных операционных системах существуют свои особенности обращения к разделяемой памяти. Мы рассмотрим наиболее популярные архитектуры: Unix(на примере Free BSD) и MS Windows. UNIX
Операционная система Free BSD для работы с разделяемой памятью использует модель nmap. Когда два процесса хотят создать область разделяемой памяти, они должны иметь какой-нибудь способ обозначения участка памяти, который они хотят разделять, и они должны иметь возможность описать его размер и начальное содержание. Системный интерфейс, описывающий область разделяемой памяти, выполняет все эти задачи, используя в качестве основы для описания сегмента разделяемой памяти файлы. Процесс создает сегмент разделяемой памяти, используя структуру данных:
caddr_t addr = nmap (
caddr_t address, /*базовый адрес*/
size_t length, /*размер области*/
int protection, /*защита области*/
int flags, /*флаги отображения*/
int fd, /*файл для отображения*/
off_t offset); /*смещение для начала отображения*/
чтобы отобразить файл, на который ссылаются посредством дескриптора fd, начиная с файлового смещения offset в свое адресное пространство, начиная с addr и в продолжение len байтов с правами доступа prot. Параметр flags дает процессу возможность указать, хочет ли он сделать разделяемое или индивидуальное отображение. Изменения, сделанные в индивидуальном отображении, обратно в файл не записываются и не видны другим процессам, в отличие от изменения в разделяемом. Два процесса, которые хотят разделять память, запрашивают отображение одного и того же файла в свое адресное пространство. Таким образом, разделяемые объекты идентифицирует существующее и хорошо понятное пространство имен файловой системы. Содержимое файлов используется в качестве начальных значений сегмента памяти. Все изменения, сделанные в отображении, отражаются обратно в содержании файла, поэтому в области разделяемой памяти можно поддерживать долгосрочное состоянии даже между различными вызовами разделяющих процессов.
Некоторые процессы хотят использовать разделяемую память исключительно в качестве краткосрочного механизма межпроцессного взаимодействия. Им нужна область памяти, которая изначально заполнена нулями и содержимое которой игнорируется после ее использования. Такие процессы не хотят после завершения работы с памятью ни платить относительно высокую цену на старте, связанную с подкачкой содержимого файл для инициализации сегмента разделяемой памяти, ни платить цену при завершении, связанную с записью модифицированных страниц обратно в файл.
Хотя для этой цели в системах Unix существует схема System V shmem, в конечном счете для механизма nmap было решено использовать все пространство имен файловой системы. Чтобы предоставить эффективный механизм для краткосрочной разделяемой памяти, была создана резидентная файловая система виртуальной памяти для временных объектов. Если нет недостатка в памяти, файлы, созданные в резидентной файловой системе виртуальной памяти, целиком находятся в оперативной памяти. Таким образом устраняется как цена начальной страничной подкачки, так и последующей обратной записи. Обычно резидентная файловая система монтируется в /tmp. Два процесса, желающие создать разделяемую область памяти, создают в /tmp файл, который они потом оба могут отобразить в свои адресные пространства.
В ходе первоначального отображения процесс может установить защиту страницы, чтобы разрешить чтение, запись и/или выполнение. Далее процесс может изменить права доступа, что часто используется отладчиками для отслеживания обращений к странице памяти, содержащей ошибочную или поврежденную структуру данных.
Чтобы обеспечить предсказуемое время выполнения в системе с разделяемой памятью, используется механизм блокировки страниц памяти, принцип которого заключается в отмене выгрузки страниц и форсирования их резидентности процессом. Пока процесс ограничивает доступ к заблокированной области своего адресного пространства, он может быть уверен, что задержки из-за отказов страниц не возникнет. Для контролирования объема доступной к блокировке памяти, система налагает необходимые ограничения.
MS Windows
В Windows существует два способа создания разделяемой секции памяти. Программист может поместить часть глобальных переменных приложения в отдельную секцию данных и установить атрибут “shared” для неё. Для этого используются директива «#pragma_section» или параметр командной строки сборщика «/SECTION». В результате единственная копия помеченных переменных будут использоваться всеми процессами, загрузившими .exe или .dll. Второй способ предполагает использование функций CreateFileMapping (см. рис. 2.1). В случае успешного выполнения данной функции создается ресурс - фрагмент памяти, доступный по имени (параметр lpname), который базируется на соответствующем объекте ядра - "объекте-файле, отображаемом в память" с присущими любому объекту атрибутами. Процессу-создателю возвращается описатель (handle) ресурса. Другие процессы, желающие иметь доступ к ресурсу, также должны получить его описатель. В данном случае это можно сделать с помощью функции OpenFileMapping, указав имя ресурса в качестве одного из параметров.
р
Рис. 2.1 Создание объекта разделяемой памяти в MS Windows
при отображении файла в память образуется регион в виртуальной памяти, а также сопутствующий ему объект-раздел или объект-секция (section object). Как и другие объекты, объекты-разделы управляются диспетчером объектов. В случае возникновения ошибок страниц подкачка осуществляется из страниц проецируемого файла, а не из общесистемного файла выгрузки.
Для таких регионов формируется массив прототипных PTE, описывающих нахождение всех страниц этого фрагмента памяти. PTE таблицы страниц процесса, выполнившего отображение, ссылаются на прототипные PTE, и тоже считаются недействительными. Если при этом другой процесс выполнил отображение этого же файла, то PTE его таблицы тоже будут ссылаться на эти же самые прототипные PTE. Таким образом, физические страницы памяти будут обобществлены.
Изменения, сделанные в данном фрагменте памяти одним процессом, будут сразу же "видны" другому процессу. Таким образом, наличие таблицы прототипных PTE обеспечивает когерентность разделяемой памяти.
Более того, если третий процесс открыл тот же самый файл для обычного ввода-вывода, то уже существующее отображение будут рассматриваться в качестве буфера кэша этого файла, доступ к которому будет осуществляться через ту же самую таблицу прототипных PTE. Таким образом, все три процесса будут работать с одной и той же версией файла.
Помимо обмена информацией между различными процессами, разделяемые страницы применяются также для передачи данных между пользовательской и ядерной частями адресного пространства процесса. Примерами могут служить передача системной информации или передача информации от драйвера ввода-вывода.
В общем же случае, выделение системой Windows сегмента разделяемой памяти ничем не отличается от выделения любого другого участка памяти - например, для кучи или стека. Функция CreateFileMapping не является специализированной для этих целей.
Пример. Создание и совместное использование сегмента разделяемой памяти двумя процессами.
В предложенных ниже кодах мы реализуем создание и обеспечение доступа к сегменту разделяемой памяти процесса 1 и процесса 2. Первый процесс создает область разделяемой памяти и специализированный объект «семафор», после чего начинает принимать строки со стандартного ввода и записывать их в разделяемую память. Второй процесс должен корректно определить область данных разделяемой памяти и считать оттуда строки, записанные первым процессом.
Первый процесс:
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int main(void)
{ key_t key;
int semid, shmid;
struct sembuf sops;
char *shmaddr;
char str[256];
key = ftok(“/usr/mash/exmpl”,'S'); /* создаем уникальный ключ */
semid = semget(key,1,0666 | IPC_CREAT); /* создаем один семафор с определенными правами доступа */
shmid = shmget(key,256, 0666 | IPC_CREAT); /*создаем разделяемую память на 256 элементов */
shmaddr = shmat(shmid, NULL, 0); /* подключаемся к разделу памяти, в shaddr -- указатель на буфер с разделяемой памятью*/
semctl(semid,0,IPC_SET, (union semun) 0); /*инициализируем семафор со значением 0 */
sops.sem_num = 0; sops.sem_flg = 0;
/* запуск бесконечного цикла */
while(1) { printf(“Введите строку:”);
if ((str = gets(str)) == NULL) break;
sops.sem_op=0; /* ожидание обнуления */
semop(semid, &sops, 1); /* семафора */
strcpy(shmaddr, str); /* копируем строку в разд. память */
sops.sem_op=3; /* увеличение семафора на 3 */
semop(semid, &sops, 1);
}
shmaddr[0]='Q'; /* укажем 2ому процессу на то, */
sops.sem_op=3; /* что пора завершаться */
semop(semid, &sops, 1);
sops.sem_op = 0; /* ждем, пока обнулится семафор */
semop(semid, &sops, 1);
shmdt(shmaddr); /* отключаемся от разд. памяти */
semctl(semid, 0, IPC_RMID, (union semun) 0); /* убиваем семафор */
shmctl(shmid, IPC_RMID, NULL); /* уничтожаем разделяемую память */
exit(0);
}
Второй процесс:
/* здесь нам надо корректно определить существование ресурса, если он есть -- подключиться, если нет -- сделать что-то еще, но как раз этого мы делать не будем*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int main(void)
{ key_t key; int semid;
struct sembuf sops;
char *shmaddr;
char st=0;
/* далее аналогично предыдущему процессу -- инициализации ресурсов */
semid = semget(key,1,0666 | IPC_CREAT);
shmid = shmget(key,256, 0666 | IPC_CREAT);
shmaddr = shmat(shmid, NULL, 0);
sops.sem_num = 0; sops.sem_flg = 0;
/* запускаем цикл */
while(st!='Q') {
printf(“Ждем открытия семафора \n”);
/* ожидание положительного значения семафора */
sops.sem_op=-2;
semop(semid, &sops, 1);
/* будем ожидать, пока “значение семафора”+”значение sem_op” не перевалит за 0, то есть если придет “3”, то “3-2=1” */
/* теперь значение семафора равно 1 */
st = shmaddr[0];
{/*критическая секция -- работа с разделяемой памятью -- в этот момент первый процесс к разделяемой памяти доступа не имеет*/}
/*после работы -- закроем семафор*/
sem.sem_op=-1;
semop(semid, &sops, 1);
/* вернувшись в начало цикла мы опять будем ждать, пока значение семафора не станет больше нуля */
}shmdt(shmaddr); /* освобождаем разделяемую память и выходим */
exit(0);}
Проблематика безопасности при работе с разделяемой памятью
В операционной системе MS Windows оба описанных выше способа доступа к разделяемой памяти уязвимы для атак, если разработчик не предусмотрел такую возможность и не принял меры заранее. Проблема с первым способом в том, что любое приложение, способное загрузить .exe или .dll, автоматически получает доступ к разделяемой секции и, таким образом, может повлиять на целевое приложение. Не следует думать, что такая уязвимость характерна только для разделяемых секций размещенных в .dll. Никто не мешает злоумышленнику загрузить .exe с помощью функции LoadLibrary и нанести ущерб системе. Фактически доступ к секции контролируется ACL на исполняемом файле, содержащим разделяемую секцию. Учитывая, что все исполняемые файлы, как правило, доступны для чтения даже из под учётной записи гостя, такая разделяемая секция доступна на запись кому угодно. Разделяемые секции, создаваемые с помощью CreateFileMapping, имеют собственный ACL. В этом плане, они несколько более надежны, чем первые. Однако и это не обеспечивает высокого уровня безопасности. Например, в случае глобального хука, все GUI приложения должны иметь доступ к его описателю. Иначе говоря, любое приложение, запущенное от имени интерактивного пользователя, будет иметь доступ к секции. Для OS Unix вопрос уязвимости стоит несколько иначе. Здесь основным направлением удара является разрешение на запись и исполнение файла, представляющего доступ к разделяемой памяти. Поскольку взаимодействие с разделяемой памятью осуществляется «по законам» работы с файловой системой, она становится точно так же уязвима для записи и запуска вредоносного кода - даже более, поскольку для получения доступа к разделяемой памяти достаточно вызвать функцию, отображающую тот же самый файл в адресное пространство сторонней программы. Таким образом, если код злоумышленника получает возможность запуска себя в системе, под ударом оказывается практически вся информация, так или иначе проходящая через каналы скоростного межпроцессного взаимодействия.
Методы защиты от того и от другого вида угрозы отстоят от тематики разделяемой памяти и заключаются в ограничении прав на работу в системе вообще всех процессов, которые потенциально способны нанести вред системе. В MS Windows дополнительно существует механизм ACL для управленя доступа к разделяемой памяти, с помощью которого также можно разграничить пользование этим адресным пространством.
Заключение
В данной работе был рассмотрен механизм использования разделяемой памяти в двух наиболее популярных в настоящий момент операционных системах. Анализ показал, что механизм разделяемой памяти, при всех предоставляемых преимуществах в скорости и удобстве использования, все же требует достаточно высокой степени аккуратности и является источником уязвимостей в системном программном обеспечении.
Тем не менее, механизм разделяемой памяти активно применяется в современных операционных системах при работе с драйверами периферийного оборудования, обращении к графическим библиотекам при проработке интерфейса пользователя, а также в любых других областях, где требуется обеспечить высокую скорость обмена небольшими порциями данных.
Список литературы
1. М.К. МакКузик, Д.В. Невилл-Нил «Free BSD: архитектура и реализация», изд. Кудиц-Образ, Москва, 2006
2. Курс лекций МГУ ВМиК «Системное Программное Обеспечение», И.В. Машечкин, 2000 г.
Подобные документы
Мониторинг системных вызовов. Системные вызовы shmget, shmat, shmctl, shmdt. Написание и внедрение модуля ядра. Выбор языка программирования. Структура программного обеспечения. Реализация мониторинга управления и удаления сегментов разделяемой памяти.
курсовая работа [91,4 K], добавлен 24.06.2009Классификация параллельных вычислительных систем. Существенные понятия и компоненты параллельных компьютеров, их компоненты. Особенности классификаций Хендера, Хокни, Флинна, Шора. Системы с разделяемой и локальной памятью. Способы разделения памяти.
курсовая работа [331,1 K], добавлен 18.07.2012Логическая структуризация и проектирование сети. Основные недостатки сети, построенной на одной разделяемой среде. Преодоление ограничений из-за использования общей разделяемой среды. Структуризация с помощью повторителей и мостов. Размер сети Ethernet.
реферат [24,0 K], добавлен 28.11.2010Запуск из одного приложения других приложений. Технология связывания и внедрения объектов. Понятие межпроцессного взаимодействия. Сценарий использования разделяемой памяти. Библиотеки динамической компоновки. Именованные и анонимные каналы, сокеты.
курсовая работа [46,5 K], добавлен 26.07.2014Схема распределения памяти, соответствующая пользовательской трактовке распределения памяти. Перемещение с помощью таблицы сегментов. Аппаратная поддержка сегментного распределения памяти. Сегментно-страничная организация памяти с двухуровневой схемой.
лекция [1,5 M], добавлен 24.01.2014Понятие виртуальной памяти, ее реализация. Особенности страничной организации по требованию. Этапы обработки ситуации отсутствия страницы в памяти. Стратегии (алгоритмы) замещения страниц. Особенности некоторых операционных систем: Windows NT и Solaris.
презентация [2,2 M], добавлен 24.01.2014Структура, специфика и архитектура многопроцессорных систем; классификация Флинна. Организация взаимного исключения для синхронизации доступа к разделяемым ресурсам. Запрещение прерываний; семафоры с драйверами устройств. Кластеры распределения нагрузки.
курсовая работа [455,9 K], добавлен 07.06.2014Классификация компьютерной памяти. Использование оперативной, статической и динамической оперативной памяти. Принцип работы DDR SDRAM. Форматирование магнитных дисков. Основная проблема синхронизации. Теория вычислительных процессов. Адресация памяти.
курсовая работа [1,5 M], добавлен 28.05.2016Принципы организации компьютерных сетей, их классификация, технологии и стандарты организации. Виды металлических кабелей. Доступ к разделяемой среде. Локальные вычислительные сети. Динамика подключений серверов. Каналы связи WAN. Беспроводные технологии.
презентация [7,9 M], добавлен 16.01.2015Сравнительный анализ статической и динамической памяти. Быстродействие и потребление энергии статической памятью. Объем памяти микросхем. Временные диаграммы чтения и записи памяти. Микросхемы синхронной и асинхронной памяти. Режимы модулей памяти.
презентация [114,2 K], добавлен 27.08.2013