Что такое процесс в компьютере

Обновлено: 03.07.2024

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

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

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

Объект задания позволяет управлять группами процессов как единым целым. Объекты заданий являются намаблеными, защищаемыми объектами, совместно используемые объекты, которые управляют атрибутами связанных с ними процессов. Операции, выполняемые над объектом задания, влияют на все процессы, связанные с объектом Job.

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

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

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

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

Рассмотрим наиболее фундаментальную абстракцию, которую ОС предоставляет пользователям: процесс. Определение процесса довольно-таки просто — это работающая программа. Программа сама по себе является безжизненной вещью, располагающейся на диске — это набор инструкций и возможно каких-то статических данных, ожидающих момента запуска. Именно ОС берет эти байты и запускает их, преобразую программу во что-то полезное.
Чаще всего пользователи хотят запускать более одной программы одновременно, например вы можете запустить на вашем ноутбуке браузер, игру, медиаплеер, текстовый редактор и тому подобное. Фактически типичная система может запускать десятки и сотни процессов одновременно. Этот факт делает систему более простой в использовании, вам никогда не приходится беспокоиться о том, свободен ли CPU, вы просто запускаете программы.

Отсюда вытекает проблема: как обеспечить иллюзию множества CPU? Как ОС создать иллюзию практически бесконечного количества CPU, даже если у вас всего один физический CPU?

ОС создает эту иллюзию посредством виртуализации CPU. Запуская один процесс, затем останавливая его, запуская другой процесс и так далее, ОС может поддерживать иллюзию того, что существует множество виртуальных CPU, хотя фактически это будет один или несколько физических процессоров. Такая техника называется разделение ресурсов CPU по времени. Эта техника позволяет пользователям запускать столько одновременных процессов, сколько они пожелают. Ценою такого решения является производительность – поскольку если CPU делят несколько процессов, каждый процесс будет обрабатываться медленнее.
Для воплощения виртуализации CPU, а особенно для того чтобы делать это хорошо, ОС нуждается и в низкоуровневой и в высокоуровневой поддержке. Низкоуровневая поддержка называется механизмами — это низкоуровневые методы или протоколы, которые реализуют нужную часть функционала. Пример такого функционала — контекстное переключение, которое дает ОС возможность останавливать одну программу и запускать на процессоре другую программу. Такое разделение по времени реализовано во всех современных ОС.
На вершине этих механизмов располагается некоторая логика, заложенная в ОС, в форме “политик”. Политика — это некоторый алгоритм принятия решения операционной системой. Такие политики, например, решают, какую программу надо запускать (из списка команд) в первую очередь. Так, например, данную задачу решит политика, называющаяся планировщик (scheduling policy) и при выборе решения будет руководствоваться такими данными как: история запуска (какая программа была запущена дольше всех за последнюю минут), какую нагрузку осуществляет данный процесс (какие типы программ были запущены), метрики производительности (оптимизирована ли система для интерактивного взаимодействия или для пропускной способности) и так далее.

Абстракция: процесс

Абстракция работающей программы, выполняемая операционной системой это то, что мы называем процесс. Как уже было сказано ранее процесс – это просто работающая программа, в любой моментальный промежуток времени. Программа с помощью которой мы можем получить суммарную информацию с различных ресурсов системы, и к которым обращается или которые эта программа затрагивает в процессе своего выполнения.
Для понимания составляющих процесса нужно понимать состояния системы: что программа может считывать или изменять во время своей работы. В любой момент времени нужно понимать, какие элементы системы важны для выполнения программы.
Одним из очевидных элементов состояния системы, которые включает в себя процесс — это память. Инструкции располагаются в памяти. Данные, которые программа читает или пишет также, располагаются в памяти. Таким образом, память, которую процесс может адресовать (так называемое адресное пространство) является частью процесса.
Также частью состояния системы являются регистры. Множество инструкций направлено на то, чтобы изменить значение регистров или прочитать их значение и таким образом регистры тоже становятся важной частью работы процесса.
Следует отметить, что состояние машины формируется также из некоторых специальных регистров. Например, IP — instruction pointer — указатель на инструкцию, которую программа исполняет в текущий момент. Еще есть stack pointer и связанный с ним frame pointer, которые используются для управления: параметрами функций, локальными переменными и адресами возврата.
Наконец, программы часто обращаются к ПЗУ (постоянному запоминающему устройству). Такая информация о “I/O” (вводе-выводе) должна включать в себя список файлов, открытых процессом в данный момент.

Process API

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

● Create (создание): В ОС должен входить какой либо метод, позволяющий создавать новый процессы. Когда вы вводите команду в терминал или запускаете приложение через двойной клик по иконке, посылается обращение к ОС для создания нового процесса и последующего запуска указанной программы.
● Удаление: Раз есть интерфейс для создания процесса, ОС также должна предоставлять возможность для принудительного удаления процесса. Большинство программ естественно будут запущены и завершены сами по себе по мере их выполнения. В противном случае пользователь хотел бы иметь возможность убить их и таким образом интерфейс для остановки процесса будет не лишним.
● Wait (ожидание): Иногда полезно дождаться завершения процесса, поэтому обеспечиваются некоторые интерфейсы предоставляющие возможностью ожидания.
● Misc Control (разное управление): Кроме убийства и ожидания процесса еще существуют другие разнообразные контролирующие методы. Например большинство ОС предоставляют возможность заморозки процесса (остановка его выполнения на некоторый период) и последующее возобновление (продолжение исполнения)
● Status (состояние): Существуют различные интерфейсы для получения некоторой информации он статусе процесса, такие как продолжительность его работы или в каком состоянии он сейчас находится.

image

Создание процесса: детали

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

В ранних ОС процесс загрузки выполнялся нетерпеливо (eagerly), то есть это значит что код загружался в память целиком до того как программа запускалась. Современные ОС делают это лениво (lazily), то есть загружая кусочки кода или данных только тогда, когда они требуются программе во время ее выполнения.

После того как код и статические данные загружены в память ОС нужно выполнить еще несколько вещей перед тем как запустить процесс. Некоторое количество памяти должно быть выделено под стек. Программы используют стек для локальных переменных, параметров функций и адресов возврата. ОС выделяет эту память и отдает ее процессу. Стек также может выделяться с некоторыми аргументами, конкретно она заполняет параметры функции main(), например массивом argc и argv.

Операционная система может также выделять некоторое количество памяти под кучу (heap) программы. Куча используется программами для явно запрашиваемых динамически выделенных данных. Программы запрашивают это пространство, вызывая функцию malloc() и явно очищает, вызывая функцию free(). Куча нужна для таких структур данных как: связанные листы, таблицы хэшей, деревья и другие. По началу под кучу выделяется маленькое количество памяти, но со временем в процессе работы программы куча может запросить большее количество памяти, через библиотечный API вызов malloc(). Операционная система вовлечена в процесс выделения большего количества памяти для того, чтобы помочь в удовлетворении этих вызовов.

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

Таким образом, загружая код и статические данные в память, создавая и инициализируя стек, а также выполняя другую работу, относящуюся к выполнению задач ввода-вывода, ОС подготавливает площадку для выполнения процесса. В конце концов, остается последняя задача: запустить на исполнение программу через ее точку ввода, называемую функцией main(). Переходя к выполнению функции main(), ОС передает управление CPU вновь созданному процессу, таким образом, программа начинает исполняться.

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

Теперь, когда у нас есть некоторое понимание, что такое процесс и как он создается, перечислим состояния процесса, в которых он может находиться. В самой простой форме процесс может находиться в одном из этих состояний:
● Running. В запущенном состоянии процесс выполняется на процессоре. Это значит, что происходит выполнение инструкций.
● Ready. В состоянии готовности процесс готов запуститься, но по каким-то причинам ОС не исполняет его в заданный момент времени.
● Blocked. В заблокированном состоянии процесс выполняет какие-то операции, которые не дают ему быть готовым к исполнению до тех пор, пока не произойдет какое-либо событие. Один из обычных примеров — когда процесс инициализирует операцию IO, он становится заблокированным и таким образом какой-то другой процесс может использовать процессор.

image

Представить себе эти состояния можно в виде графа. Как мы можем видеть на картинке, состояние процесса может меняться между RUNNING и READY на усмотрение ОС. Когда состояние процесса меняется с READY, на RUNNING это означает, что процесс был запланирован. В обратную сторону — снят с планировки. В момент, когда процесс становится BLOCKED, например, инициализирую операцию IO, ОС будет держать его в этом состоянии до наступления некоторого события, например завершение IO. в этот момент переход в состояние READY и возможно моментально в состояние RUNNING, если так решит ОС.
Давайте взглянем на пример того, как два процесса проходят через эти состояния. Для начала представим, что оба процесса запущены, и каждый использует только CPU. В этом случае, их состояния будут выглядеть следующим образом.

image

В следующем примере первый процесс через некоторое время работы запрашивает IO и переходит в состояние BLOCKED, предоставляя другому процессу возможность запуска (РИС 1.4). ОС видит, что процесс 0 не использует CPU и запускает процесс 1. Во время выполнения процесса 1 — IO завершается и статус процесса 0 меняется на READY. Наконец процесс 1 завершился, а по его окончание процесс 0 запускается, исполняется и заканчивает свою работу.

image

Структура данных

ОС сама является программой, и также как и любая другая программа имеет некоторые ключевые структуры данных, которые отслеживают разнообразные релевантные куски информации. Для отслеживания состояния каждого процесса в ОС будет поддерживаться некоторый process list для всех процессов в состоянии READY и некоторую дополнительную информацию для отслеживания процессов, которые выполняются в текущий момент. Также, ОС должна отслеживать и заблокированные процессы. После завершения IO, ОС обязана пробудить нужный процесс и перевести его в состояние готовности к запуску.

Так, например, ОС должна сохранить состояние регистров процессора. В момент остановки процесса состояние регистров сохраняется в адресном пространстве процесса, а в момент продолжения его работы — восстановить значения регистров и таким образом продолжить выполнения этого процесса.

Кроме состояний ready, blocked, running существуют еще некоторые другие состояния. Иногда в момент создания процесс может иметь состояние INIT. Наконец процесс может быть помещен состояние FINAL, когда он уже завершился, но информация о нем еще не вычищена. В UNIX системах такое состояние называется процесс-зомби. Это состояние полезно для случаев когда родительский процесс хочет узнать код возврата потомка, например, обычно 0 сигнализирует об успешном завершении, а 1 об ошибочном, однако программисты могут делать дополнительные коды вывода, сигнализируя о разных проблемах. При завершении процесс-родитель делает последний системный вызов, например wait(), чтобы дождаться завершения работы процесса-потомка и просигнализировать ОС о том, что можно очистить любые данные, связанные с завершенным процессом.


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

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

Операционная система контролирует следующую деятельность, связанную с процессами:

  1. создание и удаление процессов
  2. планирование процессов
  3. синхронизация процессов
  4. коммуникация процессов
  5. разрешение тупиковых ситуаций

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

Содержание

Создание процесса

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

  • При запуске ОС;
  • При появлении запроса на создание процесса.

Инициализация

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

В UNIX системах устанавливаются строгая иерархия процессов по принципу родитель потомок. Родитель имеет право контролировать работу потомка, приостанавливать или завершать его выполнение. Потомок не имеет никаких прав по отношению к родителям, «братьям», «дядям».

В Windows системах нет жесткой иерархии. Все процессы - равноправны. Ни один процесс (кроме ядра ОС) не имеет право контролировать работу другого процесса. Так же, в силу реализации Windows, один и тот же процесс может оказываться на различных уровнях прав.

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

Порождение нового процесса

Порождение нового процесса это длительная процедура, так как ОС должна выполнить множество действий:

  1. Выделить процессу необходимые ресурсы (адресное пространство, файлы, устройство и т.д.);
  2. Произвести инициализацию этих ресурсов (загрузить выполняемую программу в ОП, инициализировать первое начальное значение регистров и стеков, открыть файлы и т.д.);
  3. Занести всю необходимую информацию в специальную таблицу, описывающую процессу в системе;
  4. Передать управление новому процессу.

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

Планирование процессов

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

Для всех ОС соблюдается следующие принципы планирования:

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

Для ОС пакетной обработки данных кроме того используются следующие критерии планирования:

  1. Максимальная пропускная способность ЭВМ в целом.
  2. Максимальное использование процессора.
  3. Минимальное время выполнения одного задания (процесса).

Для интерактивных ОС при планировании ведется учет того, что ОС должна обладать минимальным временем отклика на запрос пользователя. Кроме того в этом случи ОС должна уметь настраиваться под пожелания отдельных пользователей.

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

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

Процесс, помимо главного рабочего состояния, может находиться в других состояниях.

Linux Процесс в ОС Linux может находиться в одном из следующих состояний:

R (running) — процесс исполняется или ожидает своей очереди;

D — непрерываемый сон (ожидает события);

S — прерываемый сон (ожидает определённого события или сигнала);

T — остановка — процесс приостановлен чем-либо;

Z (zombie) — процесс уже завершился, но ещё не передал родительскому процессу свой код возврата.

Взаимоблокировка процессов

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

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

В итоге ЭВМ нужно будет заново перезагружать. Для майнфрейма каждая перезагрузка аналогична потере нескольких миллионов долларов, такова цена за невыполненные вовремя различные запросы. Имеются различные способы выхода из блокировок:

  1. Снятие оператором выполняющихся процессов до тех пор, пока не исчезнет взаимоблокировка. Этот путь эффективен лишь в том случае, когда количество выполняющихся процессов не очень велико (не превышает 100). При большом количестве выполняющихся процессов этот путь чаще всего не помогает преодолеть блокировку.
  2. Перезагрузка системы этот путь преодоления блокировок наиболее радикальный, но и наиболее дорогой.
  3. Рестарт системы с так называемой контрольной точки.

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

Имеются два противоположных способа борьбы с взаимоблокировками:

  1. Полное игнорирование угроз возникновения взаимоблокировок.
  2. Построение такой ОС, которая просчитывает на несколько шагов вперед ситуацию, которая может возникнуть в ЭВМ после запуска определенного процесса. Такое построение ОС ведет к существенному усложнению ее структуры, однако не решает проблемы на 100%, так как любая сложная программа имеет большое количество не выявленных ошибок.

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

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

Процесс (задача) – абстракция, описывающая выполняющуюся в рамках ОС программу. Для ОС процесс – единица работы, которая потребляет системные ресурсы.

Задачи, решаемые подсистемой управления процессами:

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

С понятием управления процессами в ОС связаны следующие технологии:

Содержание

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

Состояние процесса в ходе жизненного цикла в ОС

В ходе жизненного цикла каждый процесс переходит из одного состояния в другое в соответствии с алгоритмом планирования процессов, реализуемым в данной операционной системе.

В состоянии ВЫПОЛНЕНИЕ в однопроцессорной системе может находиться только один процесс, а в каждом из состояний ОЖИДАНИЕ и ГОТОВНОСТЬ - несколько процессов, эти процессы образуют очереди соответственно ожидающих и готовых процессов. Жизненный цикл процесса начинается с состояния ГОТОВНОСТЬ, когда процесс готов к выполнению и ждет своей очереди. При активизации процесс переходит в состояние ВЫПОЛНЕНИЕ и находится в нем до тех пор, пока либо он сам освободит процессор, перейдя в состояние ОЖИДАНИЯ какого-нибудь события, либо будет насильно "вытеснен" из процессора, например, вследствие исчерпания отведенного данному процессу кванта процессорного времени. В последнем случае процесс возвращается в состояние ГОТОВНОСТЬ. В это же состояние процесс переходит из состояния ОЖИДАНИЕ, после того, как ожидаемое событие произойдет.

State of the process.jpg

Информация о процессе:

  • Режим работы процессора.
  • Информация об открытых файлах.
  • Регистры.
  • Состояние внешних устройств.
  • Операции ввода – вывода.

Информационные структуры описывающие процессы

Существует две информационные структуры по-разному описывающие процессы - контекст процесса и дескриптор процесса.

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

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

В состав контекста процесса входит:

  1. содержимое регистров процессора (включает счётчик команд, т.е. на каком этапе находится процесс);
  2. размещение кодового сегмента;
  3. информацию об открытых данным процессом файлах;
  4. информацию о работах с внешними устройствами (+ коды ошибок выполненных процессором, системных вызовов, незавершенных операциях ввода-вывода).

Дескриптор процесса

Дескриптор процесса – это информационная структура, которая описывает внешнюю структуру (информацию) процессе (нужна планировщику для выполнения процесса, а так же нужна ядру в течение всего жизненного цикла процесса)

В состав дескриптора входят:

  1. Идентификатор процесса;
  2. Состояние процесса.
  3. Информация о привилегированности процесса.
  4. Информация о расположении кодового сегмента.

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

Алгоритмы планирования процессов в ОС

Задача планирования процессов состоит из трех действий:

  1. Определение момента времени для смены, выполняемого в данный момент, процесса.
  2. Выбор того процесса из очереди готовности, которому будет передано управление.
  3. Переключение контекста (переключение между процессами).

Первые два действия выполняются на программном уровне (специально написанный код) и относятся к планированию, третье – на аппаратном уровне и относится к диспетчеризации.

Создание процесса

Создание процесса:

  • ОС создает контекст и дескриптор процесса.
  • Загрузка кодового сегмента в оперативную память.
  • Дескриптор помещается в очередь процессов, находящихся в готовности.

С этого момента можно считать, что процесс стартовал.

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

Алгоритмы планирования процессов

В зависимости от того, какие критерии накладываются, алгоритмы планирования могут основываться на:

Алгоритмы, основанные на квантовании времени

Алгоритмы, основанные на квантовании времени – любому процессу на выполнение отводится определенный квант времени (несколько милисекунд). Переключение активного процесса происходит если:

  • Истек срок времени, выделенного на выполнение процесса.
  • Процесс завершился.
  • Процесс перешел в состояние ожидания.

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


Выбор новых процессов может быть построен по принципам:

Алгоритмы, основанные на приоритетах

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

Существует 2 разновидности таких алгоритмов:

  • Использующие относительные приоритеты.
  • Использующие абсолютные приоритеты.

Алгоритмы планирования с относительными приоритетами – активный процесс выполняется пока не завершится или не перейдет в состояние ожидания.

Алгоритмы планирования с абсолютными приоритетами – смена процесса происходит в тот момент, когда в системе появляется процесс, приоритет которого выше приоритета выполняемого процесса.

Реально используются смешанные схемы планирования.

Вытесняющий и невытесняющий алгоритмы планирования

Существует два основных типа процедур планирования процессов - вытесняющие (preemptive) и невытесняющие (non-preemptive).

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

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

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

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

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

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

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

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

Однако почти во всех современных операционных системах, ориентированных на высокопроизводительное выполнение приложений (UNIX, Windows NT, OS/2), реализована вытесняющая многозадачность. Вытесняющую многозадачность часто называют истинной многозадачностью.

Синхронизация процессов в ОС

Проблема синхронизации процессов

Рассмотрим пример: в системе два прикладных процесса, которые будут работать с очередью печати.

Читайте также: