Главная страница  Межпроцессное взаимодействие (состязание) 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 [ 140 ] 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187

столько просты, что выделять для них отдельные процедуры не имеет смысла. Вызовы getuid и getgid возвращают как реальные, так и эффективные значения UID (идентификатор пользователя) и GID (идентификатор группы).

Установить GID или UID несколько сложнее, чем просто прочитать. Сначала нужно проверить, уполномочен ли процесс менять эти значения. Если проверка пройдена, об изменении GID или UID необходимо информировать файловую систему, так как эти значения влияют на защиту файлов. Вызов setsid создает новый сеанс, этого нельзя делать процессу, который уже является лидером группы. После проверки работу вызова завершает файловая система, делая процесс лидером группы без управляющего терминала.

Таблица 4.6. Системные вызовы, поддерживаемые mm/getset.c Системный вызов Описание

getuid Возвращает реальный и эффективный идентификаторы пользователя

getgid Возвращает реальный и эффективный идентификаторы группы

getpid Возвращает идентификаторы процесса и его родителя

setuid Устанавливает реальный и эффективный идентификаторы

пользователя

setgid Устанавливает реальный и эффективный идентификаторы группы

setsid Создает новый сеанс и возвращает идентификатор процесса

getpgrp Возвращает идентификатор группы процессов

Минимальную поддержку отладки посредством системного вызова ptrace обеспечивает код из файла trace.c. Системный вызов ptrace умеет выполнять одиннадцать различных команд, перечисленных в табл. 4.7. Четыре из них, enable, exit, resume и step, обрабатываются менеджером памяти. Здесь же выполняются запросы на начало и завершение трассировки. Все прочие запросы перенаправляются задаче системы, имеющей доступ к таблице процессов ядра. За это отвечает функция sys trace. В конце файла trace.c есть две вспомогательные функции, нужные для трассировки. Это функция stop proc, которая останавливает трассируемый процесс, получивший сигнал, и функция findproc, помогающая do trace найти отлаживаемый процесс в таблице процессов.

4.8.8. Утилиты менеджера памяти

Оставшиеся файлы содержат вспо.могательные процедуры и таблицы. Файл alloc.с помогает системе отслеживать, какие участки памяти заняты, а какие свободны. В нем определено четыре точки входа:

♦ alloc mem - запрос блока памяти заданного размера;

♦ free mem - возврат блока памяти;

♦ max hole - вычисляет размер самого большого свободного блока ( дыры );

♦ memjnit - инициализирует список свободных блоков при запуске менеджера памяти.



Как уже было сказано ранее, функция alloc mem просто ищет в списке первый блок подходящего размера. Если она обнаруживает достаточно большой блок, она отрезает от него нужную часть, а лишнее оставляет в списке. Если требуется весь блок, вызывается функция deLslot, которая полностью удаляет блок из списка.

Таблица 4.7. Команды отладки, поддерживаемые mm/trace.с

Команда Описание

T STOP Останавливает процесс

Т ОК Включает трассировку процесса родителем

T GETINS Возвращает значение из пространства команд

T GETDATA Возвращает значение из области данных

T GETUSER Возвращает значение из таблицы процессов пользователя

T SETINS Записывает значение в пространство команд

T SETDATA Записывает значение в область данных

T SETUSER Записывает значение в таблицу процессов пользователя

T RESUME Возобновляет выполнение

Т ЕХ1Т Выход

T STEP Устанавливает бит трассировки

Функция free mem должна проверять, можно ли объединить возвращенный блок с соседними. Если это возможно, вызывается merge, которая объединяет указанные блоки и обновляет список.

Функция max hole сканирует список свободных блоков и возвращает самое большое из найденных ею значений. Начальный список, охватывающий всю доступную память, строится функцией memjnit.

Процедуры из следующего файла, utility.c, используются в различных местах по всему коду менеджера памяти. Процедура allowed проверяет, предоставлен ли доступ к файлу. Эта функция необходима, например, do exec, чтобы проверить, является ли файл исполняемым.

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

Когда менеджер памяти обнаруживает ошибку, после которой невозможно восстановление, он вызывает функцию panic. Она сообщает об ошибке задачи системе, которая со скрежетом останавливает несущуюся в пропасть MINIX. Просто так эта функция не вызывается - не делайте этого.

Последняя функция в utility.c, tell fs, подготавливает сообщение и отправляет его файловой системе, когда последнюю необходимо информировать об обработанных менеджером памяти событиях.

Две подпрограммы из файла putk.с также являются утилитами, хотя и несколько иного типа, чем предыдущие. Время от времени в коде менеджера памяти встречаются вызовы printf, большей частью для отладки. Функция panic также вызывает printf. Ранее уже упоминалось, что в данном случае имя printf в действительности является макросом, разворачиваемым в printk, то есть эти вызовы не



используют стандартные процедуры ввода/вывода, работающие через файловую систему. Функции putk и printk напрямую общаются с задачей терминала, что запрещено обычным пользователям. Процедуры с точно такими же названиями мы видели в коде ядра.

Резюме

в этой главе были проанализированы как общие принципы управления памятью, так и их реализация в MINIX. Мы увидели, что в простейших системах вообще нет свопинга или страничной организации памяти. Программа, загруженная в память, остается там до своего завершения. Некоторые операционные системы позволяют находиться в памяти одновременно только одному процессу, в то время как другие поддерживают многозадачность.

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

Современные компьютеры часто поддерживают некоторую форму виртуальной памяти. В простейшем виде адресное пространство каждого процесса делится на части постоянного размера, называемые страницами, которые могут размещаться в любом доступном страничном блоке в памяти. Существует множество алгоритмов замещения страниц, два наилучших - это алгоритмы старения и алгоритм второй попытки . Для хорошей работы страничных систем недостаточно выбора алгоритма; кроме этого, необходимо обратить внимание на такие вопросы, как определение рабочего набора, стратегию предоставления памяти и размер страниц.

Сегментация помогает в управлении структурами данных, изменяющими свой размер во время выполнения, и упрощает процессы компоновки и совместного доступа. Она также облегчает предоставление различных видов защиты разным сегментам. Иногда сегментация и разбивка на страницы комбинируются, чтобы обеспечить двумерную виртуальную память. Системы MULTICS и Intel Pentium поддерживают сегментацию и страничную организацию памяти.

Управление памятью в MINIX реализовано просто. Процессу выделяется память, когда он делает системный вызов fork или exec. После того как участок памяти выделен, он никогда не меняет своих размеров, пока работает процесс. На машинах с Intel-процессорами MINIX реализует для процессов две модели памяти. У маленьких программ инструкции и данные могут размещаться в одном сегменте. В более сложных программах адресные пространства данных и кода могут быть выделены. Такие процессы могут разделять общий код, поэтому при вызове fork им выделяется память лишь под данные и стек. Такое не исключено и при вызове exec, если окажется, что в памяти уже находится процесс, использующий тот же код, что нужен новой программе.



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 [ 140 ] 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187

© 2000 - 2018 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования.