Управление процессами в Linux
В классической системе UNIX средства управления процессами разделяют создание процесса и запуск новой программы на две различные операции:
· Системный вызов fork создает новый процесс
· Новая программа запускается с помощью системного вызова exec.
В UNIX процесс содержит всю информацию, которую ОС должна поддерживать для реализации концепции отдельного исполнения отдельной программы.
В системе Linux свойства процесса делятся на три группы: идентификацияпроцесса, его окружениеи контекст.
Идентификатор процесса (PID)- уникальный идентификатор процесса (число); используется для указания процессов в операционной системе, когда приложение выполняет системный вызов signal, modifyили waitдля другого процесса.
Полномочия (Credentials).Каждый процесс должен иметь связанный с ним идентификатор пользователяи один или более идентификаторов групп, определяющих права процесса для доступа к системным ресурсам и файлам.
Идентификация личности (Personality).Хотя это и нетрадиционно для систем типа UNIX, в Linux каждый процесс имеет уникальный идентификатор личности, с помощью которого возможна некоторая модификация семантики ряда системных вызовов. Он используется главным образом в библиотеках эмуляции, для запроса о совместимости системных вызовов с тем или иным специфическим диалектом UNIX.
Окружениепроцесса наследуется от процесса-родителя. Состоит из двух векторов, завершающихся нулями:
· Вектор аргументовсодержит список аргументов командной строки, использованный при вызове исполняемой программы; традиционно начинается с имени самой программы
· Вектор окружения– список пар "NAME=VALUE", которые связывают переменные окружения с заданными именами и их произвольные текстовые значения.
Передача переменных окружения между процессами и наследование этих переменных дочерними процессами – гибкие средства передачи информации компонентам системного программного обеспечения, работающим в непривилегированном режиме.
Механизм переменных окружения обеспечивает средства настройки ОС, которые могут устанавливаться для каждого процесса отдельно, а не путем конфигурирования системы в целом.
Контекст процесса– это постоянно изменяющееся состояние исполняемой программы в любой момент времени.
Контекст планирования– наиболее важная часть контекста процесса; это информация, которую использует планировщик для приостановки и запуска процесса.
Ядро поддерживает хранение статистической информации о ресурсах, потребляемых в каждый момент каждым процессом и общем объеме ресурсов, использованным каждым процессом с момента его созданияпо настоящий момент.
Таблица файлов– это вектор указателей на системные файловые структуры. При выполнении системных вызовов для ввода-вывода процессы ссылаются на эти структуры с помощью индексов в таблице файлов.
В то время как таблица файлов содержит список открытых файлов, контекст файловой системыприменяется для запросов об открытии новых файлов. Здесь хранятся ссылки на текущую корневую ( root ) директорию и рабочую ( default ) директорию для поиска файлов.
Таблица обработчиков сигналовопределяет подпрограммы в адресном пространстве процесса, которые должны быть вызваны при возникновении соответствующих сигналов.
Контекст виртуальной памяти процессаопределяет все содержимое его персонального адресного пространства.
Процессы и потоки.Linux использует одно и то же внутреннее представление для процессов и потоков. Потокв Linux – это новый процесс, который использует общее адресное пространство с процессом-родителем.
Различие проявляется только в случае, когда новый поток создается системным вызовом clone:
· классический системный вызов forkсоздает новый процесс со своим полностью новым контекстом;
· системный вызов cloneсоздает новый процесс со своим новым идентификатором личности, но такой, которому разрешено совместно использовать структуры данных со своим родителем.
Использование системного вызова cloneдает процессам возможность явного контроля над тем, какие ресурсы совместно используются потоками.
Планирование задач ядра и синхронизация в ядре
Напомним, что планирование – это распределение операционной системой процессорного времени между различными задачами. В то время как в большинстве ОС под планированием понимается запуск иприостановка процессов, в Linux планирование также включает выполнение различных задач ядра. Выполнение задач ядра включает как задания, запрошенные данным процессом, так и задания, исполняемые в процессе работы драйверов.
Запрос на исполнение в режиме ядра может возникнуть в двух случаях:
· Исполняемая программа может запросить сервис ОС, как явно с помощью системного вызова, так и неявно, например, при отказе страницы
· Драйвер устройства может сгенерировать аппаратное прерывание, в результате которого процессор начнет исполнять в режиме ядра обработчик данного прерывания.
Синхронизация в ядре требует, чтобы критические секции ядра исполнялись без их прерывания другими критическими секциями.
Linux использует два метода для защиты критических секций:
· Обычный код ядра - не прерываемый. Если получено прерывание по времени, в момент, когда процесс исполняет подпрограмму системного сервиса ядра, флаг need_reschedслужит для указания того, чтобы запустился планировщик, когда завершится системный вызов и управление должно быть передано непривилегированному коду.
· Второй метод применяется к критическим секциям ядра, которые исполняются в сервисах обработки прерываний. Используя аппаратуру процессора, управляющую прерываниями, для отключения прерываний во время исполнения критической секции, ядро гарантирует, что оно может исполняться без риска одновременного обращения к общим структурам данных.
Во избежание потери производительности, ядро Linux использует архитектуру синхронизации, которая позволяет большим критическим секциям исполняться без необходимости отключения прерываний на все время исполнения критической секции.
Службы обработки прерываний делятся на верхнюю половину( top half ) и нижнюю половину( bottom half ):
· Верхняя половина – это обычная процедура обработки прерываний, исполняемая с отключением рекурсивных прерываний
· Нижняя половина исполняется при включенном режиме прерываний, с использованием мини-планировщика, который обеспечивает, чтобы нижние половины не прерывали друг друга.
Эта архитектура дополняется механизмом для выбора нижних половин при исполнении обычного кода ядра.
На рис. 3 изображены уровни защиты прерываний.
Рис. 3.Уровни защиты прерываний.
Код каждого уровня может быть прерван кодом более высокого уровня, но никогда не будет прерван кодом того же или более низкого уровня.
Пользовательский процесс может быть всегда прерван другим процессом, если происходит прерывание для планирования в режиме разделения времени.
Linux использует два алгоритма планирования процессов:
· Алгоритм разделения времени для равноправного планирования с прерываниями между различными процессами
· Алгоритм реального времени для случая, когда абсолютные приоритеты более важны, чем равноправность.
Класс планирования процесса определяет, какой именно алгоритм применить.
Для процессов с разделением времени Linux использует алгоритм на основе доверия (credits) с приоритетами ( priority ). Правило credits := credits / 2 + priority учитывает как историю процесса, так и его приоритет. По такой системе автоматически определяются приоритеты интерактивных процессов или исполняющих ввод-вывод.
Linux реализует классы планирования: FIFO и round-robin; в обоих случаях каждый процесс имеет приоритет, а не только определенный класс планирования.
Планировщик запускает процесс с наивысшим приоритетом; для процессов с одним и тем же приоритетом, он исполняет процесс, который дольше всего ждал.
FIFO – процессы исполняются до их завершения или блокировки.
round-robin – процесс будет прерван через некоторое время и помещен в конец очереди планирования, так что RR-процессы одинакового приоритета автоматически разделяют время между собой.
Версия Linux 2.0 была первым ядром Linux, поддерживающим SMP-оборудование; различные процессы или потоки могут исполняться параллельно на нескольких процессорах.
Для соблюдения требований ядра об исполнении без прерываний, SMP накладывает следующее ограничение: не более чем один процесс в каждый момент может исполнять код в режиме ядра.
Ключевые термины
GNU General Public License (GPL)– лицензия, согласно которой используется и распространяется Linux: программист, использующий Linux, либо создающий свои собственные системы на базе Linux, не имеетправа превращать свой продукт в коммерческий; программное обеспечение, распространяемое на основе GPL, не может распространяться только в виде двоичного кода (т.е. в поставку Linux должен быть включен исходный код).
Загружаемый модуль ядра( loadable kernel module, LKM ) – механизм Linux, обеспечивающий возможность компиляции, загрузки и выгрузки отдельных модулей кода ядра, независимо от остальной части ядра.
Идентификатор процесса (PID)- уникальный идентификатор процесса (число), используемое для указания процессов в операционной системе.
Контекст процесса– состояние исполняемой программы в любой момент времени; состоит из контекста планирования, контекста системы файлов, таблицы обработчиков сигналов и контекста виртуальной памяти.
Окружение процесса– системная структура, состоящая из двух векторов, завершающихся нулями: вектор аргументов командной строки процесса и вектор (переменных) окружения процесса.
Краткие итоги
Система Linux – популярная ОС, созданная в начале 1990-х гг. с целью разработки UNIX-совместимой ОС с открытым исходным кодом. Создатель Linux – Линус Торвальдс. Основная часть Linux полностью оригинальна и не содержит ведомственного конфиденциального кода.
Linux использует разработки BSD UNIX, AT&T UNIX, библиотеку X Windows. Разработка Linux поддерживается сетью разработчиков, связанных через Интернет.
Дистрибутивы Linux имеют стандартный формат (RPM), что обеспечивает совместимость между многочисленными диалектами Linux.
Ядро Linux распространяется на условиях GNU General Public License, суть которых в том, что разработки на основе кода Linux нельзя использовать для коммерческих целей, и распространение ПО, разработанного на основе Linux, должно включать исходные коды.
Linux в основном используется как серверная ОС. Доля ее использования как клиентской ОС очень мала.
Linux – свободно распространяемая полнофункциональная ОС с полным набором UNIX-совместимых инструментов. Обеспечивается совместимость с POSIX. Linux API соответствует UNIX SVR4, но неUNIX BSD.
Linux состоит из ядра, системных библиотек и системных утилит. Код ядра исполняется в привилегированном режиме. Системные библиотеки и утилиты исполняются в пользовательском режиме.
Важное новшество в Linux – механизм динамически загружаемых модулей ядра, который дает возможность отдельно компилировать, загружать, запускать и выгружать модули ядра. Компоненты модуля ядра – управление загрузкой модуля, регистрация драйверов и разрешение конфликтов.
Для управления процессами в Linux для каждого процесса создаются и используются его идентификация, окружение и контекст.
Для поддержки многопоточности в Linux используется системный вызов clone, который создает новый процесс в адресном пространстве процесса-родителя.
В отличие от многих ОС, планирование в Linux включает также и планирование задач ядра. Синхронизация в ядре требует, чтобы критическая секция одной части ядра не прерывалась другими критическими секциями.
При обработке прерываний все прерывания разделены на верхнюю половину (обычная обработка прерываний, с отключением рекурсивных прерываний) и нижнюю половину, исполняемую при включенном режиме прерываний с использованием мини-планировщика.
При планировании процессов в Linux учитываются кредиты и приоритеты. Используются классы планирования FIFO и round-robin.
Linux поддерживает симметричное мультипроцессирование (SMP).
Вопросы для самопроверки:
1. Что такое Linux?
2. Каковы основные цели и принципы разработки Linux?
3. Что такое дистрибутивы Linux и в каком формате они распространяются?
4. По какой лицензии распространяется Linux и в чем суть этой лицензии?
5. Для каких применений чаще используется Linux – как клиентская или как серверная ОС?
6. С каким стандартом API для UNIX-подобных систем совместима Linux?
7. Какому диалекту UNIX соответствуют системные библиотеки Linux?
8. Из каких основных групп кода состоит реализация Linux?
9. В чем принципиальная новизна в управлении модулями ядра Linux, по сравнению с большинством остальных ОС?
10. Каково назначение компоненты управление модулем?
11. Каково назначение компоненты регистрация драйверов?
12. Какие системные структуры создаются для процесса в Linux?
13. Что такое идентификатор процесса?
14. Что такое окружение процесса?
15. Что такое контекст процесса?
16. Каким системным вызовом создается поток в Linux?
17. Какова принципиальная особенность планирования процессов в Linux, с точки зрения обработки модулей ядра?
18. Каковы требования к исполнению критических секций при синхронизации в ядре Linux?
19. Каковы особенности верхней и нижней половин прерываний при обработке прерываний в Linux?
20. Какие принципы используются при планировании процессов в Linux?
21. Какие стратегии планирования процессов используются в Linux?
22. Какой распространенный тип многопроцессорных архитектур поддерживает Linux?
Упражнения
1. Инсталлируйте на своем домашнем компьютере систему Linux. Для инсталляции создайте на диске отдельный раздел (partition) утилитой Partition Magic. Инсталлируйте систему в полном объеме.
2. Перечислите и проанализируйте состав пакетов (RPM) дистрибутива Linux.
3. Широко известно, что Google Android – операционная система для мобильных устройств, разработанная на основе ядра Linux. Насколько, по-Вашему, соответствуют действия разработчиков Google Androidлицензии GPL, на основе которой распространяется Linux?
4. Разработайте простой динамически загружаемый модуль ядра Linux (выдающий на консоль сообщение о своем запуске), в соответствии с принципами, описанными в лекции, и поэкспериментируйте с добавлением нового модуля в систему.
5. Проанализируйте и изучите исходные коды Linux и на их основе напишите обзор используемых методов управления процессами, планирования и диспетчеризации в Linux.