DeepEdit!

Программирование баз данных на Oracle, техническая документация, литература, статьи и публикации

  • Увеличить размер шрифта
  • Размер шрифта по умолчанию
  • Уменьшить размер шрифта

Управление процессами операционной системы

правление процессами операционной системы

С точки зрения операционной системы ядро Oracle - это обычное при­ложение. В его работе нет ничего мистического - это просто огромная и весьма впечатляющая программа на языке C. Для полного понима­ния хронометрических данных, предоставляемых ядром Oracle, необ­ходимо поближе познакомиться с возможностями самого ядра, в свою очередь предоставляемых ему операционной системой.
В этом разделе мы уделим основное внимание поведению операцион­ных систем, основанных на UNIX. Изложенный здесь материал доста­точно адекватно описывает поведение клонов UNIX, таких как Linux, Sun Solaris, HP-UX, IBM AIX и Tru64. Но сведения из этого раздела будут интересны и тем, кто работает с MS Windows. Те же, кто работа­ет с какой-то другой ОС, должны будут обратиться за дополнительной информацией к руководству по этой ОС.
Я считаю, что лучшее описание функционирования процесса в контек­сте современной ОС дал Морис Бах (Maurice Bach) в своей книге «The Design of the Unix Operating System» (Архитектура операционной сис­темы Unix, [Bach 1986 (31)]). Рисунок 2.6 из этой книги, озаглавлен­ный «Process States and Transitions» (Состояния процесса и переходы между ними) и воспроизведенный на рис. 7.1, будет отправной точкой моего рассказа. На этой схеме каждый узел (прямоугольник) представляет состояние, которое процесс может принимать в операционной сис­теме. Каждое ребро (направленная линия) - это переход из одного со­стояния в другое. Можно воспринимать состояния как существитель­ные, а переходы - как глаголы, которые вызывают переход процесса из одного состояния в следующее.
Большая часть процессов ядра Oracle проводит основную часть своего времени в состоянии выполнения пользователем (user running), назы­ваемом также пользовательским, или непривилегированным, режи­мом (user mode). Разбор SQL, сортировка строк, чтение блоков кэша буферов и преобразование типов данных - все эти операции Oracle вы­полняет в пользовательском режиме. Переход процесса из пользова­тельского режима в привилегированный (kernel mode) может быть инициирован одним из двух событий. Вам необходимо понимат ь оба варианта такого перехода, поэтому рассмотрим их более подробно.
Переход по системному вызову
Когда процесс, находящийся в пользовательском режиме, совершает вызов операционной системы, он переходит в привилегированный ре­жим. К типичным системным вызовам относятся read и select. В при­вилегированном режиме процесс наделяется специальными полномо­чиями, которые позволяют ему манипулировать низкоуровневыми аппаратными компонентами и произвольными ячейками памяти. Например, в привилегированном режиме процесс может управлять устройствами ввода/вывода, такими как сокеты и дисковые устройст­ва [Bovet and Cesati (2001) 8].
Можно ожидать, что многие системные вызовы будут проводить в ожи­дании ответа от устройства очень много процессорных циклов. Напри­мер, вызов read для дисковой подсистемы сегодня обычно выполняет­ся за время порядка нескольких миллисекунд. Многие же нынешние процессоры способны выполнить миллионы инструкций за то время, пока будет выполняться единственная операция физического дисково­го ввода/вывода. Так что за время одного вызова чтения можно выпол­нить порядка миллиона инструкций процессора. Естественно, создате­ли эффективных системных вызовов чтения учитывают этот факт и организуют свой код таким образом, чтобы освободить процессор для других программ на то время, когда процесс чтения находится в ожидании.
Рассмотрим некий процесс ядра Oracle, выполняющий системный вы­зов чтения для получения блока данных Oracle с диска. После выдачи запроса к предположительно «медленному» устройству, код системно­го вызова read переведет вызывающий процесс в состояние ожидания (sleep), в котором процесс будет ожидать прерывания, оповещающего о завершении операции ввода/вывода. Такая учтивость со стороны процесса позволяет другому готовому к выполнению (ready to run) процессу занять те циклы процессора, которые в любом случае не бы­ли бы доступны процессу чтения.
Когда устройство ввода/вывода сигнализирует о готовности операции ввода/вывода ожидающего процесса к дальнейшей обработке, процесс активизируется, т. е. переходит в состояние готовности к выполне­нию. А с процессом, готовым к выполнению, может работать плани­ровщик. Этот процесс, выбранный планировщиком для исполнения, будет возвращен в привилегированный режим, в котором и будет вы­полнена оставшаяся часть кода вызова read (например, передача дан­ных, полученных от канала ввода/вывода, в оперативную память). Последняя инструкция подпрограммы read возвращает управление вызывающей программе (нашему процессу ядра Oracle), т. е. процесс переходит обратно в пользовательский режим. В этом состоянии про­цесс ядра Oracle продолжает потреблять время процессора в неприви­легированном режиме до тех пор, пока не возникнет следующее пре­рывание и не будет сделан очередной системный вызов.

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

Переход по прерыванию
Второй путь в схеме состояний процессов операционной системы обра­зован переходами по прерыванию (interrupt). Прерывание - это меха­низм, посредством которого периферийное устройство ввода/вывода, системные часы или какое-то другое устройство может асинхронно прервать работу процессора [Bach (1986) 16]. Я уже говорил о том, по­чему периферийное устройство ввода/вывода может прервать процесс. Конфигурация большинства систем такова, что системные часы поро­ ждают прерывание каждую сотую долю секунды (т. е. раз в сантисе-кунду). По получении прерывания от таймера каждый процесс систе­мы, находящийся в пользовательском режиме, сохраняет свой кон­текст (образ того, чем занимался процесс) и выполняет специальную подпрограмму операционной системы - планировщик (scheduler). Пла­нировщик определяет, следует ли позволить процессу продолжить вы­полнение или же произвести его вытеснение.
Прерывание обслуживания (preemption) переводит процесс из приви­легированного состояния в состояние готовности к выполнению, осво­бождая тем самым путь для возвращения какого-то другого процесса из состояния готовности к выполнению в пользовательский режим [Bach (1986) 148]. Именно таким образом большая часть современных операционных систем реализует разделение времени. Любой процесс, находящийся в состоянии готовности к выполнению, обрабатывается именно так, как было описано: процесс становится доступным плани­ровщику и т. д. Понимание вытеснения (приоритетного прерывания обслуживания) по таймеру необходимо для осознания материала, из­ложенного далее в главе при описании одной из основных причин «пропуска данных» в файле трассировки Oracle.
Другие состояния и переходы
Я уже упоминал о существовании более сложной схемы переходов меж­ду состояниями процесса, чем та, которая приведена на рис. 7.1. Дейст­вительно, обсудив четыре состояния процесса и семь переходов, пред­ставленных на рис. 7.1, Бах далее в своей книге приводит более слож­ную схему переходов состояний процессов [Bach (1986) 148]. На этой схеме подробно рассмотрены действия, выполняемые во время перехо­дов: вытеснение, подкачка, ветвление и даже создание процессов-зом­би. Тем, чьи приложения работают в Unix-системах, я бы настойчиво рекомендовал добавить в свою библиотеку книгу Баха.
Для рассмотрения оставшегося материала главы нам будем вполне достаточно рис. 7.1. Надеюсь, вы согласитесь с тем, что изображенные на нем состояния процессов упрощают понимание временных статис­тик Oracle.

 









jAntivirus