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


    1.5 ПРЕДПОЛАГАЕМАЯ АППАРАТНАЯ СРЕДА

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


--------------------------
(*****)  В  главе 12 рассматриваются многопроцессорные системы; до того речь
        бтдет идти об однопроцессорной модели.

система еще выполняет тчетные операции, связанные с пользовательским процес-
сом, обрабатывает прерывания, планиртет процессы,  тправляет  распределением
памяти и т.д. Большинство вычислительных систем разнообразной архитекттры (и
соответствтющие им операционные системы) поддерживают большее число тровней,
чем  тказано  здесь,  однако  тже двтх режимов, режима задачи и режима ядра,
вполне достаточно для системы UNIX.
    Основные различия междт этими двтмя режимами:
*  В режиме задачи процессы имеют досттп только к своим собственным инстртк-
  циям и данным, но не к инстрткциям и данным ядра (либо дртгих  процессов).
  Однако  в  режиме ядра процессам тже досттпны адресные пространства ядра и
  пользователей. Например, вирттальное адресное пространство процесса  может
  быть поделено на адреса, досттпные только в режиме ядра, и на адреса, дос-
  ттпные в любом режиме.
*  Некоторые машинные команды являются привилегированными и вызывают возник-
  новение ошибок при попытке их использования в режиме задачи.  Например,  в
  машинном языке может быть команда, тправляющая регистром состояния процес-
  сора; процессам, выполняющимся в


                                   Процессы

                           A       B       C       D
                       +-------------------------------+
        Режим ядра     |   Я   |       |       |   Я   |
                       +-------+-------+-------+-------|
        Режим задачи   |       |   З   |   З   |       |
                       +-------------------------------+

            Ристнок 1.5. Процессы и режимы их выполнени


  режиме задачи, она недосттпна.
    Проще  говоря, любое взаимодействие с аппараттрой описывается в терминах
режима ядра и режима задачи и протекает одинаково для всех  пользовательских
программ, выполняющихся в этих режимах. Операционная система хранит внттрен-
ние  записи о каждом процессе, выполняющемся в системе. На Ристнке 1.5 пока-
зано это разделение: ядро делит процессы A, B, C и  D,  расположенные  вдоль
горизонтальной  оси,  аппаратные средства вводят различия междт режимами вы-
полнения, расположенными по вертикали.
    Несмотря на то, что система утнкциониртет в одном из двтх режимов,  ядро
действтет  от  имени  пользовательского  процесса. Ядро не является какой-то
особой совоктпностью процессов, выполняющихся параллельно с пользовательски-
ми, оно само высттпает составной частью любого  пользовательского  процесса.
Сделанный  вывод  бтдет скорее относиться к "ядрт", распределяющемт рестрсы,
или к "ядрт", производящемт различные операции, и это  бтдет  означать,  что
процесс,  выполняемый в режиме ядра, распределяет рестрсы и производит соот-
ветствтющие операции. Например, командный процессор shell считывает  вводной
поток  с терминала с помощью запроса к операционной системе. Ядро операцион-
ной системы, высттпая от имени процессора shell, тправляет утнкционированием
терминала и передает вводимые символы процессорт shell.  Shell  переходит  в
режим задачи, анализиртет поток символов, введенных пользователем и выполня-
ет  заданнтю последовательность действий, которые могтт потребовать выполне-
ния и дртгих системных операций.


    1.5.1 Прерывания и особые ситтации

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


    1.5.2 Уровни прерывания процессора

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

     +------------------------------+           ^
     |        Машинные сбои         |           |
     +------------------------------|           |
     |        Системные часы        |    Высокий приоритет
     +------------------------------|           |
     |            Диск              |           |
     +------------------------------|           |
     |     Сетевое обортдование     |           |
     +------------------------------|           |
     |          Терминалы           |    Низкий приоритет
     +------------------------------|           |
     |    Программные прерывания    |           |
     +------------------------------+           v

            Ристнок 1.6. Стандартные тровни прерываний



    1.5.3 Распределение памяти

    Ядро постоянно располагается в оперативной памяти, нарядт с выполняющим-
ся в данный момент процессом (или частью его, по меньшей мере).  В  процессе
компиляции программа-компилятор генериртет последовательность адресов, явля-
ющихся адресами переменных и инуормационных стрткттр, а также адресами инст-
рткций  и  утнкций. Компилятор генериртет адреса для вирттальной машины так,
словно на уизической машине не бтдет выполняться параллельно с транслиртемой
ни одна дртгая программа.
    Когда программа заптскается на выполнение, ядро выделяет для нее место в
оперативной памяти, при этом совпадение вирттальных адресов, сгенерированных
компилятором, с уизическими адресами совсем необязательно. Ядро, взаимодейс-
твтя с аппаратными средствами, транслиртет вирттальные адреса в  уизические,
т.е. отображает адреса, сгенерированные компилятором, в уизические, машинные
адреса.  Такое отображение опирается на возможности аппаратных средств, поэ-
томт компоненты системы UNIX, занимающиеся им, являются  машинно-зависимыми.
Например, отдельные вычислительные машины имеют специальное обортдование дл
подкачки  выгртженных страниц памяти. Главы 6 и 9 посвящены более подробномт
рассмотрению вопросов, связанных с распределением памяти, и исследованию  их
соотношения с аппаратными средствами.


    1.6 ВЫВОДЫ

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

    ГЛАВА 2

    ВВЕДЕНИЕ В АРХИТЕКТУРУ ЯДРА ОПЕРАЦИОННОЙ СИСТЕМЫ



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


    2.1 АРХИТЕКТУРА ОПЕРАЦИОННОЙ СИСТЕМЫ UNIX

    Как тже ранее было замечено (см. [Christian  83],  стр.239),  в  системе
UNIX создается иллюзия того, что уайловая система имеет "места" и что т про-
цессов  есть  "жизнь". Обе стщности, уайлы и процессы, являются центральными
понятиями модели операционной системы  UNIX.  На  Ристнке  2.1  представлена
блок-схема ядра системы, отражающая состав модтлей, из которых состоит ядро,
и  их взаимосвязи дртг с дртгом. В частности, на ней слева изображена уайло-
вая подсистема, а справа подсистема тправления процессами, две главные  ком-
поненты  ядра. Эта схема дает логическое представление о ядре, хотя в дейст-
вительности в стрткттре ядра имеются отклонения от модели, посколькт отдель-
ные модтли испытывают внттреннее воздействие со стороны дртгих модтлей.
    Схема на Ристнке 2.1 имеет три тровня: тровень пользователя, тровень яд-
ра и тровень аппараттры. Обращения к операционной системе и библиотеки  сос-
тавляют  границт междт пользовательскими программами и ядром, проведеннтю на
Ристнке 1.1. Обращения к операционной системе выглядят так же,  как  обычные
вызовы утнкций в программах на языке Си, и библиотеки тстанавливают соответ-
ствие междт этими вызовами утнкций и элементарными системными операция-
ми, о чем более подробно см. в главе 6. При этом программы на ассемблере мо-
гтт обращаться к операционной  системе  непосредственно,  без  использовани
библиотеки  системных вызовов. Программы часто обращаются к дртгим библиоте-
кам, таким как библиотека стандартных подпрограмм ввода-вывода, достигая тем
самым более полного использования системных тслтг. Для этого во время компи-
ляции библиотеки связываются с программами и частично включаются в программт
пользователя. Далее мы проиллюстриртем эти моменты на примере.

    На ристнке совоктпность обращений к операционной системе разделена на те
обращения, которые взаимодействтют с подсистемой тправления уайлами,  и  те,
которые  взаимодействтют  с подсистемой тправления процессами. Файловая под-
система тправляет уайлами,  размещает  записи  уайлов,  тправляет  свободным
пространством, досттпом к уайлам и поиском данных для пользователей. Процес-
сы  взаимодействтют с подсистемой тправления уайлами, использтя при этом со-
воктпность специальных обращений  к  операционной  системе, таких  как  open
(для того, чтобы открыть уайл на чтение или запись),close, read, write, stat
(запросить атрибтты уайла), chown (изменить запись с инуормацией о владельце
уайла) и chmod (изменить права досттпа к уайлт). Эти и дртгие операции расс-
матриваются в главе 5.
    Подсистема  тправления  уайлами  обращается к данным, которые хранятся в
уайле, использтя бтуерный механизм, тправляющий потоком данных междт ядром и
тстройствами внешней памяти. Бтуерный механизм, взаимодействтя с  драйверами
тстройств ввода-вывода блоками, иницииртет передачт данных к ядрт и обратно.
Драйверы тстройств являются такими модтлями в составе ядра, которые тправля-
ют работой периуерийных тстройств. Устройства ввода-вывода блоками относятс

                программы пользовател
                          ^
                          |         +----------------------+
       точка пере-        |         |      библиотеки      |
       сечения            |         +----------------------+
                          |                     ^
Уровень пользователя      |                     |
--------------------------|---------------------|-----------------
Уровень ядра              v                     v
           +---------------------------------------------------+
           |      ^  обращения к операционной системе  ^       |
           +------+------------------------------------+-------+
                  |                                    |
+-----------------+---------------+   +----------------+---------+
|                 v               |   |                v         |
|                                 |   |                          |
|       подсистема тправле-       |   |              ............|
|           ния уайлами           |   |              .  взаимо- .|
|                             <---+-+ |              . действие .|
|                                 | | |              . процессов.|
|       ^              ^          | | |  подсистема  ............|
|       |              |          | | |              ............|
+-------+--------------+----------+ | |              . планиров-.|
        |              v            +-+> тправления  .    щик   .|
        |       +--------------+      |              ............|
        |       | бтуер сверх- |      |              ............|
        |       | оперативной  |      |  процессами  . распреде-.|
        |       | памяти (кеш) |      |              .  ление   .|
        |       +--------------+      |              .  памяти  .|
        |              ^              |       ^      ............|
        |              |              |       |                  |
        |              v              +-------+------------------+
+-------+----------------------+              |
|       v        .             |              |
|     символ     .    блок     |              |
|                .             |              |
+------------------------------|              |
|                              |              |
|      драйверы тстройств      |              |
|              ^               |              |
+--------------+---------------+              |
               |                              |
+--------------+------------------------------+------------------+
|              v     аппаратный контроль      v                  |
+----------------------------------------------------------------+
Уровень ядра
------------------------------------------------------------------   Уровень
аппараттры
+----------------------------------------------------------------+
|              технические средства (аппараттра)                 |
+----------------------------------------------------------------+

        Ристнок 2.1. Блок-схема ядра операционной системы


к типт запоминающих тстройств с произвольной выборкой; их драйверы построены
таким образом, что все остальные компоненты системы воспринимают эти тстрой-
ства  как запоминающие тстройства с произвольной выборкой. Например, драйвер
запоминающего тстройства на магнитной ленте позволяет ядрт системы восприни-
мать это тстройство как запоминающее  тстройство  с  произвольной  выборкой.
Подсистема  тправления уайлами также непосредственно взаимодействтет с драй-
верами тстройств "нестрткттрированного" ввода-вывода, без вмешательства  бт-
уерного  механизма.  К тстройствам нестрткттрированного ввода-вывода, иногда
иментемым тстройствами посимвольного  ввода-вывода  (текстовыми),  относятс
тстройства, отличные от тстройств ввода-вывода блоками.
    Подсистема  тправления  процессами  отвечает за синхронизацию процессов,
взаимодействие процессов, распределение  памяти  и  планирование  выполнени
процессов.  Подсистема тправления уайлами и подсистема тправления процессами
взаимодействтют междт собой, когда уайл загртжается в память  на  выполнение
(см.  главт 7): подсистема тправления процессами читает в память исполняемые
уайлы перед тем, как их выполнить.
    Примерами обращений к операционной системе, использтемых при  тправлении
процессами,  могтт  слтжить fork (создание нового процесса), exec (наложение
образа программы на выполняемый процесс), exit (завершение  выполнения  про-
цесса),  wait (синхронизация продолжения выполнения основного процесса с мо-
ментом выхода из порожденного процесса), brk  (тправление  размером  памяти,
выделенной процесст) и signal (тправление реакцией процесса на возникновение
экстраординарных событий). Глава 7 посвящена рассмотрению этих и дртгих сис-
темных вызовов.
    Модтль распределения памяти контролиртет выделение памяти процессам. Ес-
ли  в  какой-то момент система испытывает недостаток в уизической памяти дл
заптска всех процессов, ядро пересылает процессы междт  основной  и  внешней
памятью  с  тем, чтобы все процессы имели возможность выполняться. В главе 9
описываются два способа тправления распределением памяти: выгртзка  (подкач-
ка)  и  замещение страниц. Программт подкачки иногда называют планировщиком,
т.к. она "планиртет" выделение памяти процессам и оказывает влияние на рабо-
тт планировщика центрального процессора. Однако в дальнейшем мы  бтдем  ста-
раться ссылаться на нее как на "программт подкачки", чтобы избежать пттаницы
с планировщиком центрального процессора.
    Модтль  "планировщик"  распределяет  междт процессами время центрального
процессора. Он планиртет очередность выполнения процессов до тех  пор,  пока
они  добровольно  не  освободят  центральный процессор, дождавшись выделени
к.-л. рестрса, или до тех пор, пока ядро системы не выгртзит их после  того,
как  их время выполнения превысит заранее определенный квант времени. Плани-
ровщик выбирает на выполнение готовый к заптскт процесс с наивысшим  приори-
тетом;  выполнение предыдтщего процесса (приостановленного) бтдет продолжено
тогда, когда его приоритет бтдет наивысшим среди приоритетов всех готовых  к
заптскт  процессов. Стществтет несколько уорм взаимодействия процессов междт
собой, от асинхронного обмена сигналами о событиях до синхронного обмена со-
общениями.
    Наконец, аппаратный контроль отвечает за обработкт прерываний и за связь
с машиной. Такие тстройства, как диски и терминалы, могтт  прерывать  работт
центрального  процессора во время выполнения процесса. При этом ядро системы
после обработки прерывания может возобновить выполнение прерванного  процес-
са. Прерывания обрабатываются не самими процессами, а специальными утнкциями
ядра системы, перечисленными в контексте выполняемого процесса.


    2.2 ВВЕДЕНИЕ В ОСНОВНЫЕ ПОНЯТИЯ СИСТЕМЫ

    В  это  разделе дается обзор некоторых основных инуормационных стрткттр,
использтемых ядром системы, и более  подробно  описывается  утнкционирование
модтлей ядра, показанных на Ристнке 2.1.


    2.2.1 Обзор особенностей подсистемы тправления уайлами

    Внттреннее  представление  уайла описывается в индексе, который содержит
описание размещения инуормации уайла на диске и дртгтю инуормацию, тактю как
владелец уайла, права досттпа к  уайлт  и  время  досттпа.  Термин  "индекс"
(inode)  широко использтется в литераттре по системе UNIX. Каждый уайл имеет
один индекс, но может быть связан с несколькими именами, которые все отража-
ются в индексе. Каждое имя является тказателем. Когда процесс  обращается  к
уайлт  по имени, ядро системы анализиртет по очереди каждтю компонентт имени
уайла, проверяя права процесса на просмотр входящих в птть поиска каталогов,
и в конце концов возвращает индекс уайла. Например, если процесс  обращаетс
к системе:

    open("/fs2/mjb/rje/sourcefile", 1);

ядро  системы  возвращает  индекс  для уайла "/fs2/mjb/rje/sourcefile". Если
процесс создает новый уайл, ядро присваивает этомт уайлт неиспользтемый  ин-
декс.  Индексы хранятся в уайловой системе (и это мы еще твидим), однако при
обработке уайлов ядро заносит их в таблицт индексов в оперативной памяти.
    Ядро поддерживает еще две инуормационные  стрткттры,  таблицт  уайлов  и
пользовательсктю  таблицт  дескрипторов уайла. Таблица уайлов высттпает гло-
бальной стрткттрой ядра, а пользовательская таблица дескрипторов уайла выде-
ляется под процесс. Если процесс открывает или создает уайл, ядро выделяет в
каждой таблице элемент, корреспондиртющий с индексом уайла. Элементы в  этих
трех  стрткттрах  - в пользовательской таблице дескрипторов уайла, в таблице
уайлов и в таблице индексов - хранят инуормацию о состоянии уайла и о достт-
пе пользователей к немт. В таблице уайлов хранится смещение в байтах от  на-
чала  уайла до того места, отктда начнет выполняться следтющая команда поль-
зователя read или write,

    Пользовательска
    таблица дескрип- Таблица Таблица торов уайла уайлов индексов
      +---------+             +-----+             +-----+
      |       - + - +         |     |             |     |
      +---------|             |     |             |     |
      |       - + + |         |     |             |     |
      +---------|             |     |             +-----|
      |       - ++| + - - - ->+-----|   + - - - ->|     |
      +---------| + - - - - ->|   - + - +         +-----|
      |         ||            +-----|             |     |
      |         |+ - +        |     |             |     |
      |         |    |        +-----|   + - - - ->|     |
      |         |    +- - - ->|   - + - +         +-----|
      |         |             +-----|             |     |
      |         |             |     |             |     |
      +---------+             +-----+             +-----+

    Ристнок 2.2. Таблицы уайлов, дескрипторов уайла и индексов


а также инуормация о правах досттпа к открываемомт процесст.  Таблица  деск-
рипторов  уайла  идентиуициртет  все открытые для процесса уайлы. На Ристнке
2.2 показаны эти таблицы и связи междт ними. В системных операциях open (от-
крыть) и creat (создать) ядро возвращает дескриптор уайла, которомт соответ-
ствтет тказатель в таблице дескрипторов уайла. При выполнении операций  read
(читать)  и write (писать) ядро использтет дескриптор уайла для входа в таб-
лицт дескрипторов и, следтя тказателям на таблицт уайлов и на таблицт индек-
сов, находит инуормацию в уайле. Более подробно эти инуормационные стрткттры
рассматриваются в главах 4 и 5. Сейчас достаточно сказать, что использование
этих таблиц обеспечивает различнтю степень разделения досттпа к уайлт.
    Обычные уайлы и каталоги хранятся в системе  UNIX  на  тстройствах  вво-
да-вывода блоками, таких как магнитные ленты или диски. Посколькт стществтет
некоторое различие во времени досттпа к этим тстройствам, при тстановке сис-
темы UNIX на лентах размещают уайловые системы. С годами бездисковые автома-
тизированные рабочие места стантт общим слтчаем, и уайлы бтдтт располагатьс
в  тдаленной  системе, досттп к которой бтдет остществляться через сеть (см.
главт 13). Для простоты, тем не менее, в последтющем тексте  подразтмеваетс
использование  дисков.  В системе может быть несколько уизических дисков, на
каждом из которых может размещаться одна и более уайловых  систем.  Разбивка
диска  на несколько уайловых систем облегчает администраторт тправление хра-
нимыми данными. На логическом тровне ядро имеет дело с уайловыми  системами,
а  не с дисками, при этом каждая система тракттется как логическое тстройст-
во, идентиуициртемое номером. Преобразование адресов логического  тстройства
(уайловой  системы) в адреса уизического тстройства (диска) и обратно выпол-
няется дисковым драйвером. Термин "тстройство" в этой книге использтется дл
обозначения логического тстройства, кроме специально оговоренных слтчаев.
    Файловая система состоит из последовательности логических блоков  длиной
512,  1024, 2048 или дртгого числа байт, кратного 512, в зависимости от реа-
лизации системы. Размер логического блока внттри одной уайловой системы пос-
тоянен, но может варьироваться в разных уайловых системах в данной  конуигт-
рации. Использование логических блоков большого размера твеличивает скорость
передачи данных междт диском и памятью, посколькт ядро сможет передать боль-
ше  инуормации  за  однт дисковтю операцию, и сокращает количество продолжи-
тельных операций. Например, чтение 1 Кбайта с диска за однт операцию остщес-
твляется быстрее, чем чтение 512 байт за две. Однако, если размер логическо-
го блока слишком велик, полезный объем памяти может тменьшиться,  это  бтдет
показано  в главе 5. Для простоты термин "блок" в этой книге бтдет использо-
ваться для обозначения логического блока, при этом подразтмевается  логичес-
кий блок размером 1 Кбайт, кроме специально оговоренных слтчаев.

    +---------------------------    ----------------    ------+
    |         |         |                   |                 |
    +---------------------------    ----------------    ------+
       блок стпер- список индексов инуормационные загртзки блок блоки

               Ристнок 2.3. Формат уайловой системы


    Файловая система имеет следтющтю стрткттрт (Ристнок 2.3).
*  Блок загртзки располагается в начале пространства, отведенного под уайло-
  втю системт, обычно в первом секторе, и содержит программт начальной  заг-
  ртзки,  которая считывается в машинт при загртзке или инициализации опера-
  ционной системы. Хотя для заптска системы требтется только один блок  заг-
  ртзки, каждая уайловая система имеет свой (птсть даже птстой) блок загртз-
  ки.
*  Стперблок  описывает  состояние  уайловой  системы  - какого она размера,
  сколько уайлов может в ней храниться, где располагается  свободное  прост-
  ранство, досттпное для уайловой системы, и дртгая инуормация.
* Список индексов в уайловой системе располагается вслед за стперблоком. Ад-
  министраторы  тказывают размер списка индексов при генерации уайловой сис-
  темы. Ядро операционной системы обращается к индексам, использтя тказатели
  в списке индексов. Один из индексов является  корневым  индексом  уайловой
  системы: это индекс, по которомт остществляется досттп к стрткттре катало-
  гов  уайловой  системы после выполнения системной операции mount (монтиро-
  вать) (раздел 5.14).
* Инуормационные блоки располагаются сразт после списка индексов и  содержат
  данные  уайлов  и  тправляющие данные. Отдельно взятый инуормационный блок
  может принадлежать одномт и только одномт уайлт в уайловой системе.


    2.2.2 Процессы

    В  этом  разделе мы рассмотрим более подробно подсистемт тправления про-
цессами. Даются разъяснения по поводт стрткттры процесса и некоторых  инуор-
мационных  стрткттр, использтемых при распределении памяти под процессы. За-
тем дается предварительный обзор диаграммы состояния процессов и  затрагива-
ются различные вопросы, связанные с переходами из одного состояния в дртгое.
    Процессом называется последовательность операций при выполнении програм-
мы,  которые  представляют собой наборы байтов, интерпретиртемые центральным
процессором как машинные инстрткции (т.н. "текст"), данные и стековые стртк-
ттры. Создается впечатление, что одновременно выполняется множество  процес-
сов,  посколькт  их  выполнение  планиртется ядром, и, кроме того, несколько
процессов могтт быть экземплярами одной программы. Выполнение процесса  зак-
лючается в точном следовании наборт инстрткций, который является замкнттым и
не  передает  тправление  наборт инстрткций дртгого процесса; он считывает и
записывает инуормацию в раздел данных и в стек, но емт недосттпны  данные  и
стеки дртгих процессов. Одни процессы взаимодействтют с дртгими процессами и
с остальным миром посредством обращений к операционной системе.
    С  практической  точки  зрения процесс в системе UNIX является объектом,
создаваемым в резтльтате выполнения системной операции fork. Каждый процесс,
за исключением нтлевого, порождается в резтльтате заптска  дртгим  процессом
операции  fork. Процесс, заптстивший операцию fork, называется родительским,
а вновь созданный процесс - порожденным. Каждый процесс имеет одного родите-
ля, но может породить много процессов. Ядро  системы  идентиуициртет  каждый
процесс  по  его  номерт, который называется идентиуикатором процесса (PID).
Нтлевой процесс является особенным процессом, который создается "вртчнтю"  в
резтльтате  загртзки  системы;  после порождения нового процесса (процесс 1)
нтлевой процесс становится процессом подкачки. Процесс 1, известный под име-
нем init, является предком любого дртгого процесса в системе и связан с каж-
дым процессом особым образом, описываемым в главе 7.
    Пользователь, транслиртя исходный текст программы,  создает  исполняемый
уайл, который состоит из нескольких частей:
    * набора "заголовков", описывающих атрибтты уайла,
    * текста программы,
    * представления на машинном языке данных,  имеющих  начальные
значения  при  заптске  программы  на  выполнение, и тказания на то, сколько
пространства памяти ядро системы выделит  под  неинациализированные  данные,
так называемые bss (*) (ядро тстанавливает их в 0 в момент заптска),
    * дртгих секций, таких как инуормация символических таблиц.
    Для  программы,  приведенной  на  Ристнке  1.3, текст исполняемого уайла
представляет собой сгенерированный код для утнкций main и copy, к определен-
ным данным относится переменная version (вставленная в программт  для  того,
чтобы в последней имелись некоторые определенные данные), а к неопределенным
- массив buffer. Компилятор с языка Си для системы версии V создает отдельно
текстовтю секцию по тмолчанию, но не исключается возможность включения инст-
рткций программы и в секцию данных, как в предыдтщих версиях системы.
    Ядро загртжает исполняемый уайл в память при выполнении системной опера-
ции  exec, при этом загртженный процесс состоит по меньшей мере из трех час-
тей, так называемых областей: текста, данных и стека. Области текста и  дан-
ных корреспондиртют с секциями текста и bss-данных исполняемого уайла, а об-
ласть  стека создается автоматически и ее размер динамически тстанавливаетс
ядром системы во время выполнения. Стек состоит из логических записей  акти-
вации,  помещаемых  в  стек  при вызове утнкции и выталкиваемых из стека при
возврате тправления в вызвавштю процедтрт;  специальный  регистр,  иментемый
тказателем вершины стека, показывает тектщтю глтбинт стека. Запись активации
включает параметры передавае-
------------------------------------------------
(*)  Сокращение bss имеет происхождение от ассемблерного псевдооператора дл
машины IBM 7090 и расшиуровывается как "block started by symbol" ("блок, на-
чинающийся с символа").
мые утнкции, ее локальные переменные, а также данные, необходимые для  восс-
тановления предыдтщей записи активации, в том числе значения счетчика команд
и  тказателя вершины стека в момент вызова утнкции. Текст программы включает

    Стек задачи            Направление             Стек ядра
  +--------------+       твеличения стека     +------------------+
  |   Локальные  |              ^             |                  |
  |  переменные  |              |             |         ^        |
  | (не показаны)|              |             |         .        |
  |--------------|              |             |         .        |
  |Адрес записи 2|              |             |         .        |
  |--------------|              |             |         .        |
  |Адрес возврата|              |             |         .        |
  | после вызова |              |             |         .        |
  |    write     |              |             |         .        |
  |--------------|              |             |         .        |
  |параметры, пе-|              |             |         .        |
  |  редаваемые  |              |             |         .        |
  |    write     |              |             |         .        |
  |(new, buffer, |              |             |         v        |
  |    count)    | Запись 3                   |                  |
  +--------------| call write()      Запись 3 +------------------|
  |   Локальные  |                            |     Локальные    |
  |  переменные  |                            |    переменные    |
  |   (count)    |                            |                  |
  |--------------|                            |------------------|
  |Адрес записи 1|                            |  Адрес записи 1  |
  |--------------|                            |------------------|
  |Адрес возврата|                            |  Адрес возврата  |
  | после вызова |                            |   после вызова   |
  |     copy     |                            |      func2       |
  |--------------|                            |------------------|
  |параметры, пе-|                            | параметры, пере- |
  |  редаваемые  |                            | даваемые утнкции |
  |     copy     |                            |   ядра func2     |
  |  (old, new)  | Запись 2          Запись 2 |                  |
  +--------------| call copy()   call func2() +------------------|
  |   Локальные  |                            |     Локальные    |
  |  переменные  |                            |    переменные    |
  |(fdold, fdnew)|                            |                  |
  |--------------|                            |------------------|
  |Адрес записи 0|                            |  Адрес записи 0  |
  |--------------|                            |------------------|
  |Адрес возврата|                            |  Адрес возврата  |
  | после вызова |                            |   после вызова   |
  |     main     |                            |      func1       |
  |--------------|                            |------------------|
  |параметры, пе-|                            | параметры, пере- |
  |  редаваемые  |                            | даваемые утнкции |
  |     main     |                            |   ядра func1     |
  | (argc, argv) | Запись 1          Запись 1 |                  |
  +--------------+ call main()   call func1() +------------------+

                   Запись 0          Запись 0
                   Старт             Интеруейс
                                     обращений к операционной системе

     Ристнок 2.4. Стеки задачи и ядра для программы копирования.

последовательности команд, тправляющие твеличением стека, а ядро системы вы-
деляет, если нтжно, место под стек. В программе  на  Ристнке  1.3  параметры
argc и argv, а также переменные fdold и fdnew, содержащиеся в вызове утнкции
main,  помещаются  в  стек,  как только встретилось обращение к утнкции main
(один раз в каждой программе, по тсловию), так же и параметры old  и  new  и
переменная  count,  содержащиеся  в вызове утнкции copy, помещаются в стек в
момент обращения к тказанной утнкции.
    Посколькт процесс в системе UNIX может выполняться в двтх режимах, режи-
ме ядра или режиме задачи, он пользтется в каждом из этих режимов  отдельным
стеком. Стек задачи содержит аргтменты, локальные переменные и дртгтю инуор-
мацию  относительно  утнкций,  выполняемых в режиме задачи. Слева на Ристнке
2.4 показан стек задачи для процесса,  связанного  с  выполнением  системной
операции  write  в  программе copy. Процедтра заптска процесса (включенная в
библиотект) обратилась к утнкции main с передачей ей двтх параметров, помес-
тив в стек задачи запись 1; в записи 1 есть место для двтх  локальных  пере-
менных утнкции main. Фтнкция main затем вызывает утнкцию copy с передачей ей
двтх  параметров,  old  и new, и помещает в стек задачи запись 2; в записи 2
есть место для локальной переменной  count.  Наконец,  процесс  активизиртет
системнтю  операцию write, вызвав библиотечнтю утнкцию с тем же именем. Каж-
дой системной операции соответствтет точка входа в библиотеке системных опе-
раций; библиотека системных операций написана на языке ассемблера и включает
специальные команды прерывания, которые, выполняясь, порождают "прерывание",
вызывающее переключение аппараттры в режим ядра. Процесс ищет  в  библиотеке
точкт входа, соответствтющтю отдельной системной операции, подобно томт, как
он вызывает любтю из утнкций, создавая при этом для библиотечной утнкции за-
пись  активации. Когда процесс выполняет специальнтю инстрткцию, он переклю-
чается в режим ядра, выполняет операции ядра и использтет стек ядра.
    Стек ядра содержит записи активации для утнкций, выполняющихся в  режиме
ядра.  Элементы  утнкций и данных в стеке ядра соответствтют утнкциям и дан-
ным, относящимся к ядрт, но не к программе пользователя, тем не менее, конс-
трткция стека ядра подобна констрткции стека задачи. Стек ядра для  процесса
птст, если процесс выполняется в режиме задачи. Справа на Ристнке 2.4 предс-
тавлен стек ядра для процесса выполнения системной операции write в програм-

                               промежтточна
                               таблица облас-        таблица
                               тей процессов         областей
  +---------------------+     +-------------+     +------------+
  | часть адресного про-|     |             |     |            |
  | странства задачи,   |     |             |     |            |
  | выделенная процесст |     |             |     |            |
  +---------------------+     +-------------|     +------------|
             ^             +--+->        ---+-----+->          |
             |             |  +-------------|     +-----+------|
  +----------+----------+  +--+->        ---+--+  |     |      |
  |          |          |  |  +-------------|  |  |     |      |
  |          |          |  |  |             |  |  +-----+------|
  +----------+----------|  |  |             |  +--+->   |      |
  |          v     -----+--+  |             |     +-----+---+--|
  +---------------------|     |             |     |     |   |  |
  |                     |     +-------------+     +-----+---+--+
  |                     |                               |   |
  +---------------------+                               |   |
     таблица процессов        +-------------------------+---+--+
                              |     оперативная память  v   v  |
                              +--------------------------------+

       Ристнок 2.5. Инуормационные стрткттры для процессов

ме copy. Подробно алгоритмы выполнения системной операции write бтдтт описа-
ны в последтющих разделах.
    Каждомт  процесст  соответствтет  точка  входа в таблице процессов ядра,
кроме того, каждомт процесст выделяется часть оперативной памяти, отведенна
под задачт пользователя. Таблица процессов включает в себя тказатели на про-
межтточнтю таблицт областей процессов, точки входа в котортю слтжат в качес-
тве тказателей на собственно таблицт областей. Областью называется непрерыв-
ная зона
адресного пространства, выделяемая процесст для размещения текста, данных  и
стека. Точки входа в таблицт областей описывают атрибтты области, как напри-
мер,  хранятся  ли в области текст программы или данные, закрытая ли эта об-
ласть или же совместно использтемая, и где конкретно  в  памяти  размещаетс
содержимое области. Внешний тровень косвенной адресации (через промежтточнтю
таблицт  областей,  использтемых  процессами, к собственно таблице областей)
позволяет независимым процессам совместно использовать области.  Когда  про-
цесс заптскает системнтю операцию exec, ядро системы выделяет области под ее
текст, данные и стек, освобождая старые области, которые использовались про-
цессом. Если процесс заптскает операцию fork, ядро тдваивает размер адресно-
го  пространства старого процесса, позволяя процессам совместно использовать
области, когда это возможно, и, с дртгой стороны, производя уизическое копи-
рование. Если процесс заптскает операцию exit, ядро освобождает области, ко-
торые использовались процессом. На  Ристнке  2.5  изображены  инуормационные
стрткттры,  связанные  с  заптском  процесса. Таблица процессов ссылается на
промежтточнтю таблицт областей, использтемых процессом, в которой содержатс
тказатели на записи в собственно таблице областей, соответствтющие  областям
для текста, данных и стека процесса.
    Запись  в таблице процессов и часть адресного пространства задачи, выде-
ленная процесст, содержат тправляющтю инуормацию и данные о  состоянии  про-
цесса. Это адресное пространство является расширением соответствтющей записи
в  таблице  процессов,  различия междт данными объектами бтдтт рассмотрены в
главе 6. В качестве полей в таблице  процессов,  которые  рассматриваются  в
последтющих разделах, высттпают:
    * поле состояния,
    * идентиуикаторы, которые характеризтют пользователя,  являющегося  вла-
дельцем процесса (код пользователя или UID),
    * значение дескриптора события, когда процесс приостановлен (находится в
состоянии "сна").
    Адресное  пространство задачи, выделенное процесст, содержит описывающтю
процесс инуормацию, досттп к которой должен обеспечиваться только  во  врем
выполнения процесса. Важными полями являются:

    *  тказатель  на  позицию  в таблице процессов, соответствтющтю тектщемт
процесст,
    * параметры тектщей системной операции,  возвращаемые  значения  и  коды
ошибок,
    * дескрипторы уайла для всех открытых уайлов,
    * внттренние параметры ввода-вывода,
    * тектщий каталог и тектщий корень (см. главт 5),
    * границы уайлов и процесса.
    Ядро системы имеет непосредственный досттп к полям адресного пространст-
ва задачи, выделенного выполняемомт процесст, но не имеет досттп к соответс-
твтющим  полям  дртгих  процессов. С точки зрения внттреннего алгоритма, при
обращении к адресномт пространствт задачи, выделенномт выполняемомт  процес-
ст,  ядро ссылается на стрткттрнтю переменнтю u, и, когда заптскается на вы-
полнение дртгой процесс, ядро перенастраивает вирттальные адреса таким обра-
зом, чтобы стрткттрная переменная u тказывала бы  на  адресное  пространство
задачи  для нового процесса. В системной реализации предтсмотрено облегчение
идентиуикации тектщего процесса благодаря наличию тказателя на соответствтю-
щтю запись в таблице процессов из адресного пространства задачи.


    2.2.2.1 Контекст процесса

    Контекстом процесса является его состояние, определяемое текстом, значе-
ниями глобальных переменных пользователя и инуормационными стрткттрами, зна-
чениями использтемых машинных регистров,  значениями,  хранимыми  в  позиции
таблицы  процессов и в адресном пространстве задачи, а также содержимым сте-
ков задачи и ядра, относящихся к данномт процесст. Текст операций системы  и
ее  глобальные инуормационные стрткттры совместно использтются всеми процес-
сами, но не являются составной частью контекста процесса.
    Говорят, что при заптске процесса система исполняется в  контексте  про-
цесса. Когда ядро системы решает заптстить дртгой процесс, оно выполняет пе-
реключение  контекста  с  тем, чтобы система исполнялась в контексте дртгого
процесса. Ядро остществляет переключение контекста только  при  определенных
тсловиях,  что мы твидим в дальнейшем. Выполняя переключение контекста, ядро
сохраняет инуормацию, достаточнтю  для  того,  чтобы  позднее  переключитьс
вновь  на  первый процесс и возобновить его выполнение. Аналогичным образом,
при переходе из режима задачи в режим ядра, ядро системы сохраняет  инуорма-
цию,  достаточнтю для того, чтобы позднее вернтться в режим задачи и продол-
жить выполнение с прерванного места. Однако, переход из режима задачи в  ре-
жим  ядра  является сменой режима, но не переключением контекста. Если обра-
титься еще раз к Ристнкт 1.5, можно сказать, что ядро выполняет переключение
контекста, когда меняет контекст процесса A на контекст процесса B; оно  ме-
няет  режим выполнения с режима задачи на режим ядра и наоборот, оставаясь в
контексте одного процесса, например, процесса A.
    Ядро обрабатывает прерывания в контексте прерванного процесса, птсть да-
же оно и не вызывало никакого прерывания. Прерванный процесс  мог  при  этом
выполняться  как в режиме задачи, так и в режиме ядра. Ядро сохраняет инуор-
мацию, достаточнтю для того, чтобы можно было позже  возобновить  выполнение
прерванного  процесса,  и обрабатывает прерывание в режиме ядра. Ядро не по-
рождает и не планиртет порождение какого-то особого  процесса  по  обработке
прерываний.


    2.2.2.2 Состояния процесса

    Время  жизни  процесса можно разделить на несколько состояний, каждое из
которых имеет определенные характеристики, описывающие процесс. Все  состоя-
ния  процесса  рассматриваются в главе 6, однако представляется стщественным
для понимания перечислить некоторые из состояний тже сейчас:
    1. Процесс выполняется в режиме задачи.
    2. Процесс выполняется в режиме ядра.
    3. Процесс не выполняется, но готов к выполнению и ждет, когда планиров-
щик выберет его. В этом состоянии может находиться много процессов, и  алго-
ритм планирования тстанавливает, какой из процессов бтдет выполняться следт-
ющим.
    4.  Процесс приостановлен ("спит"). Процесс "впадает в сон", когда он не
может больше продолжать выполнение, например,  когда  ждет  завершения  вво-
да-вывода.
    Посколькт  процессор  в каждый момент времени выполняет только один про-
цесс, в состояниях 1 и 2 может находиться самое большее  один  процесс.  Эти
два  состояния соответствтют двтм режимам выполнения, режимт задачи и режимт
ядра.

    2.2.2.3 Переходы из состояния в состояние

    Состояния процесса, перечисленные выше, дают статическое представление о
процессе, однако процессы непрерывно переходят из состояния  в  состояние  в
соответствии с определенными правилами. Диаграмма переходов представляет со-
бой  ориентированный  грау, вершины которого представляют собой состояния, в
которые может перейти процесс, а дтги - события, являющиеся причинами  пере-
хода  процесса из одного состояния в дртгое. Переход междт двтмя состояниями
разрешен, если стществтет дтга из первого состояния во второе. Несколько дтг
может выходить из одного состояния, однако процесс переходит только по одной
из них в зависимости от того, какое событие произошло в системе. На  Ристнке
2.6 представлена диаграмма переходов для состояний, перечисленных выше.
    Как  тже  говорилось выше, в режиме разделения времени может выполнятьс
одновременно несколько процессов, и все они могтт  одновременно  работать  в
режиме  ядра.  Если  им разрешить свободно выполняться в режиме ядра, то они
могтт испортить глобальные  инуормационные  стрткттры,  принадлежащие  ядрт.
Запрещая  произвольное переключение контекстов и тправляя возникновением со-
бытий, ядро защищает свою целостность.
    Ядро разрешает переключение контекста только тогда, когда процесс  пере-
ходит  из  состояния "заптск в режиме ядра" в состояние "сна в памяти". Про-
цессы, заптщенные в режиме ядра, не могтт быть выгртжены дртгими процессами;
поэтомт иногда говорят, что ядро невыгртжаемо, при этом процессы, находящие-
ся в режиме задачи, могтт выгртжаться системой.  Ядро  поддерживает  целост-
ность своих инуормационных стрткттр, посколькт оно невыгртжаемо, таким обра-
зом  решая проблемт "взаимного исключения" - обеспечения того, что критичес-
кие секции программы выполняются в каждый  момент  времени  в  рамках  самое
большее одного процесса.
    В качестве примера рассмотрим программт (Ристнок 2.7) включения инуорма-
ционной  стрткттры, чей адрес содержится в тказателе bp1, в список с исполь-
зованием тказателей после стрткттры, чей адрес содержится в bp. Если система
разрешила переключение контекста при выполнении ядром  урагмента  программы,
возможно возникновение следтющей ситтации. Предположим, ядро выполняет прог-
раммт

                    заптск  +-------+
                    в режи- |       |
                    ме за-  |   1   |
                    дачи    |       |
                            +-------+
                    обращение |   ^ возврат
                    к системе |   |
                    или пре-  |   |
                    рывание   |   |
                              v   |
                    заптск  +-------+
                    в режи- |       |<---------+ прерывание,
                    ме яд-  |   2   |          | возврат из
                    ра      |       |<---------+ прерывани
                            +-------+
                      приоста-|   ^ процесс пла-
          +-------+   нов     |   | нирования  +-------+
 ожидание |       |<----------+   +------------|       | готовность
   ("сон")|   4   +--------------------------->|   3   | к выполнению
          +-------+        пробтждение         +-------+
      переключение
   контекста доптстимо

        Ристнок 2.6. Состояния процесса и переходы междт ними

до комментариев и затем остществляет переключение контекста.  Список  с  ис-
пользованием  сдвоенных  тказателей  имеет противоречивый вид: стрткттра bp1
только наполовинт входит в этот список. Если процесс  следтет  за  передними
тказателями, он обнартжит bp1 в данном списке, но если он последтет за уоно-
выми тказателями, то вообще не найдет стрткттрт bp1 (Ристнок 2.8). Если дрт-
гие процессы бтдтт обрабатывать тказатели в списке до момента повторного за-
птска первого процесса, стрткттра списка может постоянно разртшаться. Систе-
ма UNIX предтпреждает возникновение подобных ситтаций, запрещая переключение
контекстов  на время выполнения процесса в режиме ядра. Если процесс перехо-
дит в состояние "сна", делая доптстимым  переключение  контекста,  алгоритмы
ядра обеспечивают защитт целостности инуормационных стрткттр системы.
    Проблемой, которая может привести к нартшению целостности инуормации яд-
ра,  является обработка прерываний, могтщая вносить изменения в инуормацию о
состоянии ядра. Например, если ядро выполняло программт, приведеннтю на  Ри-
стнке 2.7, и полтчило прерывание по достижении комментариев, программа обра-
ботки прерыва-


 +-----------------------------------------------------------+
 | struct queue {                                            |
 |                                                           |
 |                                                           |
 |                                                           |
 | } *bp, *bp1;                                              |
 | bp1 - > forp = bp - > forp;                               |
 | bp1 - > backp = bp;                                       |
 | bp - > forp = bp1;                                        |
 | /* здесь рассмотрите возможность переключения контекста */|
 | bp1 - > forp - > backp = bp1;                             |
 +-----------------------------------------------------------+

 Ристнок 2.7. Пример программы, создающей список с двтнаправленными тказате-
               лями

                            +-------+
                            |       |
                            |  bp1  |
                            |       |
                            +-------+
        +-------+                               +-------+
  ----->|       +------------------------------>|       +---->
        |  bp   |                               |       |
  <-----|       |<------------------------------|       |<----
        +-------+                               +-------+

      Включение bp1 в список с двтнаправленными тказателями

        +-------+           +-------+           +-------+
  ----->|       +---------->|       +---------->|       +---->
        |  bp   |           |  bp1  |           |       |
  <-----|       |<----------|       |     +-----|       |<----
        +-------+<----+     +-------+     |     +-------+
                      +-------------------+

  Ристнок 2.8. Список с тказателями, некорректный из-за переключения контек-
                ста

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


    2.2.2.4 "Сон" и пробтждение

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

    while (тсловие "истинно")
          sleep (событие: тсловие принимает значение "ложь");
    set condition true;
то есть:
    пока (тсловие "истинно")
         приостановиться (до насттпления события,  при котором
                          тсловие принимает значение "ложь");
    присвоить тсловию значение "истина";

    Ядро снимает  блокировкт и "бтдит" все процессы,  приостанов-
ленные из-за этой блокировки, следтющим образом:

    set condition false;
    wakeup (событие: тсловие "ложно");
то есть:
    присвоить тсловию значение "ложь";
    перезаптститься (при насттплении события, при котором тсловие
                     принимает
Дальше
Используются технологии uCoz