Основные принципы управления процессором и процессами

Основные понятия

Подсистема управления процессами является одной из наиболее важных в операционной системе. В ее функции входит создание, уничтожение и обеспечение взаимодействия между процессами, а также распределение между ними процессорного времени. Определим понятия процесса и потока. В юните “Основы операционных систем” уже было дано простейшее определение процесса. Однако начиная с 1960-х годов в вычислительных системах используется мультипрограммирование, или мультизадачность (multitasking) – способ организации вычислительного процесса, при котором на одном процессоре выполняются сразу несколько программ. В совместном использовании этих программ находятся и другие ресурсы системы: оперативная память, дисковое пространство, данные.

Основными критериями для оценки эффективности вычислительной системы являются:

- пропускная способность – количество задач, выполняемых вычислительной системой в единицу времени;

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

- реактивность системы.

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

Каждая работа вычислительной системы заключается в выполнении некоторой программы. Вследствие этого как с процессом, так и с потоком связан программный код, для выполнения которого должны быть выделены ресурсы (процессорное время, оперативная память, дисковое пространство, устройства ввода-вывода, определенные файлы на диске и т.д.). Если в операционной системе существует и процесс, и поток, процесс с точки зрения ОС является заявкой на потребление любых видов ресурсов, кроме одного – процессорного времени. Потоки же являются теми единицами работы, между которыми распределяется процессорное время. Свое название эти единицы работы получили вследствие того, что они представляют собой последовательности (потоки) выполнения команд. В самом простейшем случае процесс может состоять только из одного потока и тогда понятие “процесс” полностью включает в себя понятие “поток” и остается только один вид единицы работы и потребления всех ресурсов вычислительной системы – процесс. Мультипрограммирование осуществляется в таких ОС на уровне процессов.

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

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

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

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

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

Таким образом, в операционной системе наряду с про­цессами нужен другой механизм распараллеливания вычислений, который учи­тывал бы тесные связи между отдельными ветвями вычислений одного и того же приложения. Для этих целей современные ОС предлагают механизм мпогопоточной обработки(multithreading). При этом вводится новая единица работы – поток выполнения, а понятие “процесс” в значительной степени меняет смысл. Понятию “поток” соответствует последовательный переход процессора от одной команды программы к другой. ОС распределяет процессорное время между пото­ками. Процессу ОС назначает адресное пространство и набор ресурсов, которые совместно используются всеми его потоками.

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

Итак, мультипрограммирование более эффективно на уровне потоков, а не процес­сов. Каждый поток имеет собственный счетчик команд и стек. Задача, оформлен­ная в виде нескольких потоков в рамках одного процесса, может быть выполнена быстрее за счет псевдопараллельного (или параллельного в мультипроцессорной системе) выполнения ее отдельных частей. Например, если электронная таблица была разработана с учетом возможностей многопоточной обработки, то пользо­ватель может запросить пересчет своего рабочего листа и одновременно продол­жать заполнять таблицу. Особенно эффективно можно использовать многопоточность для выполнения распределенных приложений, например многопоточный сервер может параллельно выполнять запросы сразу нескольких клиентов.

Использование потоков связано не только со стремлением повысить производи­тельность системы за счет параллельных вычислений, но и с целью создания более читабельных, логичных программ. Введение нескольких потоков выполне­ния упрощает программирование. Например, в задачах типа “писатель-читатель” один поток выполняет запись в буфер, а другой считывает записи из него. По­скольку они разделяют общий буфер, не стоит их делать отдельными процесса­ми. Другой пример использования потоков – управление сигналами, такими, как прерывание с клавиатуры (del или break). Вместо обработки сигнала прерывания один поток назначается для постоянного ожидания поступления сигналов. Та­ким образом, использование потоков может сократить необходимость в прерыва­ниях пользовательского уровня. В этих примерах не столь важно параллельное выполнение, сколь важна ясность программы.

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

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

В однопрограммном режиме

Рассмотрим задачу управления процессором для однопрограммных операционных систем. В такой ОС существует два процесса: системный процесс – процесс выполнения программ ОС и пользовательский процесс – процесс выполнения программ пользователя.

Системный процесс существует постоянно: с момента загрузки операционной системы и до конца ее работы. Он может быть заблокирован (например, ждать команды пользователя на выполнение программы).

Переключение “пользовательский процесс – системный процесс” в однопрограммной ОС связано со следующими событиями в вычислительной системе:

- завершение пользовательского процесса;

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

Переключение “системный процесс – пользовательский процесс” связано с:

- созданием пользовательского процесса;

- завершением выполнения функций ОС, используемых пользовательским процессом.

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

Наши рекомендации