- •Операционные системы
- •VI. Планирование процессов
- •1. Процессы и организация планирования процессов
- •1.5. Жизненный цикл процесса в unix-системах.
- •1.5.1. Состояния процесса в unix-системах:
- •1.5.2. Этапы жизненного цикла процесса.
- •1.6. Переключение контекста процесса.
- •1.7. Приоритеты процессов.
- •1.8. Синхронизация процессов.
- •2. Основные понятия планирования процессов
- •2.1. Ситуации, при которых необходимо планирование процессов.
- •2.2. Основные системы планирования процессов.
- •3. Планирование процессов в системах пакетной обработки
- •3.1. Принцип планирования процессов Первый пришел – первым обслужен (fifo - First In Fist Out).
- •3.2. Принцип планирования процессов Кратчайшая задача – первая.
- •3.3. Принцип планирования процессов Наименьшее оставшееся время выполнения.
- •3.4. Принцип трехуровневого планирования процессов.
1.6. Переключение контекста процесса.
Переключение между процессами, необходимое для распределения вычислительного ресурса, выражается в переключении контекста, когда контекст выполнявшегося процесса запоминается, а восстанавливается контекст процесса, выбранного планировщиком процессов. Переключение процесса является достаточно ресурсоемкой операцией, поскольку, кроме сохранения состояния регистров процесса, ядро должно выполнить множество других действий.
Контекст переключается в четырех случаях:
1. текущий процесс переходит в состояние сна, ожидая недоступного ресурса (3);
2. текущий процесс завершает свое выполнение (7);
3. если существует более высокоприоритетный процесс в очереди на выполнение после пересчета приоритетов;
4. происходит пробуждение более высокоприоритетного процесса.
Первые два случая соответствуют добровольному переключению контекста, и действия ядра достаточно просты – ядро вызывает процедуру переключения контекста из функций sleep или exit. Третий и четвертый случаи происходят не по воле процесса, который в это время выполняется в режиме ядра, поэтому не может быть немедленно приостановлен. В этой ситуации ядро устанавливает специальный флаг runrun, который указывает, что в очереди находится более высокоприоритетный процесс, требующий предоставления вычислительных ресурсов. Перед переходом процесса из режима ядра в режим задачи ядро проверяет этот флаг и, если он установлен, вызывает функцию переключения контекста.
1.7. Приоритеты процессов.
Планирование процессов в UNIX-системах, как правило, основано на приоритетах процессов, т. к. планировщик процессов выбирает процесс с наивысшим приоритетом.
Приоритет процесса не является фиксированным и динамически изменяется системой в зависимости от использования вычислительных ресурсов, времени ожидания запуска и текущего состояния процесса.
Если процесс готов к запуску и имеет наивысший приоритет, планировщик процессов приостанавливает выполнение текущего процесса (с более низким приоритетом), даже если последний не выработал свой временной квант.
Ядро UNIX-систем является непрерываемым (nonpreemptive), что означает – процесс, находящийся в режиме ядра (в результате системного вызова или прерывания) и выполняющий системные инструкции, не может быть прерван системой, а вычислительные ресурсы передаются другому высокоприоритетному процессу. Выполняющийся процесс не может освободить процессор по собственному желанию в результате недоступности какого-либо ресурса, перейдя в состояние сна. В противном случае, система может прервать выполнение процесса только при переходе из режима ядра в пользовательский режим. Такой подход значительно упрощает решение задач синхронизации и поддержки целостности структур данных ядра.
Процессы, выполняющиеся в пользовательском режиме, имеют более низкий приоритет, чем работающие в режиме ядра.
1.8. Синхронизация процессов.
Процессы должны синхронизироваться при доступе к совместно используемым ресурсам.
Использование явных примитивов для синхронизации порождает серьезные проблемы при написании, отладке и сопровождении программ, поэтому в традиционных UNIX-системах понятие процесса жестко связывается с понятием отдельной и недоступной для других процессов виртуальной памятью, когда каждый процесс защищен ядром операционной системы от неконтролируемого вмешательства других процессов. Но связывание процесса с виртуальной памятью, в свою очередь, порождает две основные проблемы:
1. первая проблема связана с системами реального времени, предназначенными для одновременного управления несколькими внешними объектами и представляющимися в виде совокупности параллельно (квазипараллельно) выполняемых потоков команд (т. е. взаимодействующих процессов). Если с каждым процессом связана отдельная виртуальная память, то переключение с выполнения одного процесса на выполнение другого является дорогостоящей операцией, поэтому традиционный подход UNIX-систем препятствовал использованию системы в приложениях реального времени;
2. вторая проблема связана с появлением симметричных мультипроцессорных компьютерных архитектур (SMP – Symmetric Multiprocessor Architectures), в которых физически присутствуют несколько процессоров, имеющих одинаковые по скорости возможности доступа к совместно используемой основной памяти – при применении традиционного подхода UNIX-систем к организации процессов наличие общей памяти не является большим достоинством.
Таким образом, более эффективным остается явное параллельное программирование с использованием параллельных процессов в общей виртуальной памяти с явной синхронизацией.
В целях синхронизации используется, так называемая, нить (thread), которая является независимым потоком управления, выполняемым в контексте некоторого процесса.
В этом случае понятие контекста процесса изменяется следующим образом: все, что не относится к потоку управления (виртуальная память, дескрипторы открытых файлов и т. д.), остается в общем контексте процесса, а все, что характерно для потока управления (регистровый контекст, стеки разного уровня и т. д.), переходит из контекста процесса в контекст нити. Все нити процесса выполняются в его контексте, но каждая нить имеет свой собственный контекст.
Контекст нити, как и контекст процесса, состоит из пользовательской и ядерной составляющих.
Пользовательская составляющая контекста нити включает индивидуальный стек нити. Поскольку нити одного процесса выполняются в общей виртуальной памяти (все нити процесса имеют равные права доступа к любым частям виртуальной памяти процесса), то стек (сегмент стека) любой нити процесса не защищен от произвольного (например, по причине ошибки) доступа со стороны других нитей.
Ядерная составляющая контекста нити включает ее регистровый контекст (в частности, содержимое регистра счетчика команд) и динамически создаваемые ядерные стеки.
