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

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

опознать, когда пользователь нажмет в консоли F1, просматривая состояние всех процессов.

В MINIX процессы могут завершать свою работу либо сделав системный вызов exit, либо получив сигнал. И в том и в другом случае менеджер памяти уведомляет ядро при помощи сообщения SYS XIT. Работу здесь выполняет функция do xit, которая сложнее, чем можно было бы ожидать. Учетная информация о процессе обрабатывается просто. Сигнальный таймер, если таковой есть, уничтожается, для этого поверх него записывается нулевое значение, исходя из того, что задача часов, когда истекает какой-либо таймер, всегда проверяет, интересен ли он кому-нибудь. Сложность do xit связана с тем, что в момент уничтожения процесс может находиться в очереди, пытаясь отправить или получить сообщение. В коде это проверяется, и если процесс обнаруживается в очереди сообщений какого-либо другого процесса, его запись аккуратно удаляется из этой очереди.

В противоположность предыдущему сообщению, которое было немного сложным, SYS GETSP обрабатывается совершенно тривиально. Это сообщение менеджер памяти использует, чтобы выяснить значение указателя стека какого-либо процесса. Последнее необходимо системным вызовам Ьгк и sbrk для того, чтобы определить, не произошло ли перекрытия сегмента данных и стека. Обработчиком сообщения является функция do getsp.

Теперь мы перейдем к одному из тех немногих сообщений, в которых заинтересована только файловая система, это сообщение SYS TIMES. Оно используется для реализации системного вызова times, возвращающего процессу-инициатору вызова информацию о процессорном времени. Все действия обработчика сводятся к тому, что он помещает запрошенные значения в ответное сообщение. Чтобы предупредить возможные состязания при доступе к счетчикам времени, его тело ограничивается вызовами lock и unlock.

Может случиться так, что менеджер памяти или файловая система обнаружат ошибку, делающую невозможной дальнейшую работу. Например, если во время запуска файловая система узнает, что главный блок корневого устройства невосстановимо поврежден, она паникует и отправляет ядру сообщение SYS AB0RT. Кроме того, суперпользователь может принудительно вернуть систему в монитор начальной загрузки или перезагрузить систему при помощи команды reboot, которая обращается к системному вызову reboot. В любом из этих случаев задача системы выполняет подпрограмму do abort, которая при необходимости копирует в монитор загрузки инструкции, после чего в завершение процесса вызывает wreboot.

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

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



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

Когда процессу нужно послать сигнал, системной задаче отправляется сообщение SYS SENDSIG. Оно обрабатывается функцией do sendsig. Необходимая для обработки POSIX-сигнала информация хранится в структуре sigcontext, поля которой содержат состояние регистров процессора, и структуре sigframe, описывающей, как сигналы должны обрабатываться процессом. Обе структуры нуждаются в инициализации, но главная задача do sendsig - поместить требуемую информацию в стек процесса-адресата и изменить значения его счетчика команд и указателя стека, чтобы в следующий раз, когда планировщик запустит процесс, был выполнен код обработчика сигнала.

Когда обработчик сигнала в стиле POSIX завершает свою работу, он не вытаскивает из стека адрес, на котором было прервано нормальное исполнение процесса, как в случае старого варианта обработки сигналов. Программист, пишущий обработчик сигнала, заканчивает его инструкцией return (на языке программирования высокого уровня), но манипуляции со стеком, произведенные вызовом sendsig, приводят к тому, что выполнение return приводит к системному вызову sigreturn. После этого менеджер памяти отправляет системной задаче сообщение SYS SIGRETURN, обрабатываемое функцией do sigreturn. Эта функция копирует структуру sigcontext обратно в адресное пространство ядра и восстанавливает регистры процесса. В следующий раз, когда планировщик запустит процесс, выполнение последнего будет продолжено, и вся информация о ранее установленных обработчиках сигналов будет сохранена.

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

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



клавиш. Сюда же относятся и сигналы об исключениях, обнаруживаемые процессором (например, деление на ноль или недопустимая инструкция). Сигналы, инициируемые файловой системой, также обрабатываются сначала в ядре. Когда файловой системе необходимо запросить у ядра генерацию подобного сигнала, она использует сообщение SYS KILL. Название этого сигнала может ввести вас в заблуждение, оно не имеет ничего общего с системным вызовом kill, с помощью которого обычные процессы посылают сигналы. Обработчиком SYS KILL служит функция do kill, которая сначала делает обычные проверки корректности данных сообщения, а затем, чтобы передать сигнал процессу, взывает cause sig. Сигналы, исходящие из ядра, также передаются через эту функцию. Она инициирует сигнал, предавая менеджеру памяти сообщение KSIG.

Закончив с одним из сигналов типа KSIG, менеджер памяти передает обратно системной задаче сообщение SYS ENDSIG. Оно обрабатывается функцией do endsig, которая уменьшает количество текущих сигналов, и, когда счетчик достигает нуля, сбрасывает у процесса бит SIGPENDING. Если после этого у процесса не остается никаких флагов, препятствующих его выполнению, вызывается lock ready, чтобы вновь разрешить процессу работать.

Сообщение SYS C0PY - одно из наиболее часто используемых. Оно необходимо для того, чтобы позволить файловой системе и менеджеру памяти копировать блоки информации в память пользовательских процессов и из нее.

Когда пользователь делает системный вызов read, файловая система смотрит, нет ли в ее кэше затребованных блоков. Если нет, она посылает соответствующей дисковой задаче сообщение с просьбой загрузить этот блок в кэш. Затем она отправляет системной задаче сообщение, указывающее ей копировать этот блок пользовательскому процессу. В худшем случае для считывания блока необходимо семь сообщений, показанных на рис. 3.29. Эти сообщения составляют значительную часть накладных расходов в MINIX, являющихся ценой модульной структуры системы.

Отступая в сторону, нужно упомянуть, что на процессорах 8086, не имеющих защиты, было достаточно просто смошенничать и позволить файловой системе скопировать данные в адресное пространство пользовательского процесса, но это бы нарушало принципы построения системы. Если кому-то, у кого есть доступ к столь древней машине, захочется увеличить за счет этого механизма производительность, ему стоит внимательно изучить его шестеренки , чтобы увидеть, от какого количества возможных проблем он избавляет себя за счет небольшой потери в эффективности. На компьютерах с процессорами Pentium, имеющими механизм защиты, подобное повышение быстродействия невозможно.

Запрос SYS C0PY обрабатывается прямолинейно. Обработчиком служит функция do copy, основные действия которой сводятся к извлечению параметров из сообщения и к вызову phys copy.

Одним из способов борьбы с неэффективностью механизма передачи сообщений является упаковка нескольких запросов в одно сообщение, в MINIX - SYS VC0PY. Это сообщение содержит указатель на массив с параметрами копирования нескольких блоков памяти. В цикле в коде функции do vcopy для каждого запроса из массива извлекаются адрес и длина исходного блока и адрес, куда его



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 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования.