- •14.Назовите последовательность операций, необходимую для:
- •15 Системные вызовы FreeBsd, реализующие функции управления процессами.
- •16. Охарактеризуйте многонитевые процессы. Поясните понятия параллельности и одновременности выполнения.
- •17 Укажите на характерные отличия между однонитевой и многонитевой реализацией процессов.
- •18 Классификация нитей. Нити ядра. Особенности реализации и рекомендуемая область применения.
- •19 Классификация нитей. Легковесные нити. Особенности реализации и рекомендуемая область применения.
18 Классификация нитей. Нити ядра. Особенности реализации и рекомендуемая область применения.
Существуют различные тины нитей, каждая из которых обладает различными свойствами и применением. В этом разделе мы опишем три важнейших их типа: нити ядра, легковесные процессы и прикладные нити.
Нити ядра
Нити ядра не требуют связи с каким-либо прикладным процессом. Они создаются и уничтожаются ядром и внутри ядра по мере необходимости и отвечают за выполнение определенных функций. Такие нити используют совместно доступные области кода и глобальные данные ядра, но обладают собственным стеком в ядре. Они могут независимо назначаться на выполнение и используют стандартные механизмы синхронизации ядра, такие как sleep() или wakeup().
Нити ядра применяются для выполнения таких операций, как асинхронный ввод-вывод. Вместо поддержки каких-либо специальных механизмов ядро просто создает новую нить для обработки запросов для каждой такой операции. Запрос обрабатывается нитью синхронно, но для ядра представляется асинхронным событием. Нити ядра могут быть также использованы для обработки прерываний. Нити ядра являются малозатратными при создании и дальнейшем использовании. Единственными используемыми ими ресурсами являются стек ядра и область, в которой сохраняется контекст регистров на период приостановки работы нити (необходимо также поддерживать некую структуру данных, хранящую информацию для назначения ее на выполнение и синхронизацию). Переключение контекста между нитями ядра также происходит быстро, так что нет необходимости обновлять отображение памяти.
Применение нитей в ядре не является новым подходом. Такие системные процессы, как pagedaemon, в традиционных системах UNIX функционально похожи на нити ядра. Процессы-демоны, наподобие nfsd (сервер Network File System), запускаются на прикладном уровне, однако после запуска полностью выполняются в ядре. После входа в режим ядра их прикладной контекст становится ненужным. Они также эквивалентны нитям ядра. Так как в традиционных системах UNIX отсутствовало понятие разделения применительно к представлению нитей ядра, такие процессы были вынуждены «таскать* за собою ненужный багаж, присущий традиционным процессам, в виде таких структур, как ргос и user. Многонитевые системы позволили реализовать демоны намного проще в качестве нитей ядра.
19 Классификация нитей. Легковесные нити. Особенности реализации и рекомендуемая область применения.
Существуют различные тины нитей, каждая из которых обладает различными свойствами и применением. В этом разделе мы опишем три важнейших их типа: нити ядра, легковесные процессы и прикладные нити.
Легковесный процесс (или LWP, lightweight process) — это прикладная нить, поддерживаемая ядром. LWP является абстракцией высокого уровня, основанной на нитях ядра. Каждый процесс может иметь один или более LWP, любой из которых поддерживается отдельной нитью ядра . Легковесные процессы планируются на выполнение независимо от процесса, но совместно разделяют адресное пространство и другие ресурсы процесса. Они обладают возможностью производить системные вызовы и блокироваться в ожидании окончания ввода-вывода или освобождения ресурсов. На многопроцессорных системах процесс в состоянии использовать преимущества настоящей параллельной работы, так как каждый LWP может выполняться на отдельном процессоре. Однако даже на однопроцессорных системах применение LWP дает существенные преимущества, поскольку при ожидании ресурсов или окончания ввода-вывода блокируется не весь процесс в целом, а только отдельные LWP.
Кроме стека ядра и контекста регистров легковесному процессу необходимо поддерживать некоторое состояние задачи, что в первую очередь включает контекст регистров задачи, который необходимо сохранять перед тем, как обслуживание LWP будет прервано. Несмотря на то что каждый LWP ассоциирован с нитью ядра, некоторые нити ядра могут выполнять системные задачи и не относиться к какому-либо LWP.
Многонитевые процессы применяются прежде всего в тех случаях, когда каждая нить является полностью независимой и редко взаимодействует с другими нитями. Код приложения является полностью вытесняемым, при этом все LWP в процессе совместно используют одно и то же адресное пространство процесса. Если доступ к каким-либо данным производится одновременно несколькими LWP, необходимо обеспечить некоторую синхронизацию доступа. Для этого ядро системы предоставляет средства блокировки разделяемых переменных, при попытке прохождения в которые LWP будут блокированы. Такими средствами являются взаимные исключения (mutual exclusion, или mutex), атрибуты защиты, или защелки (locks), семафоры и условные переменные, которые будут более подробно рассмотрены в главе 7.
Рассказывая о легковесных процессах, необходимо также упомянуть и об их ограничениях. Многие операции над такими процессами, например создание, уничтожение и синхронизация, требуют применения системных вызовов. Однако системные вызовы по ряду причин являются весьма затратными операциями. Каждый вызов требует двух переключений режима. сначала из режима задачи в режим ядра и обратное переключение после завершения работы функции. При каждом переключении режима I.WP пересекает границу защиты (protection boundary). Ядро должно скопировать все параметры системного вызова из пространства задачи в пространство ядра и привести их при необходимости в корректное состояние для защиты обработчиков этих вызовов от вредоносных или некорректно работающих процессов. При возврате из системного вызова ядро должно скопировать данные обратно в пространство задачи.
Когда легковесным процессам необходимо часто пользоваться разделяемыми данными, затраты на синхронизацию могут свести на нет увеличение производительности от их применения. Многие многопроцессорные системы поддерживают блокировку ресурсов, которая может быть активизирована из прикладного уровня при условии отсутствия удержания данного ресурса другой нитью Если нити необходим ресурс, который в данный момент недоступен, она может выполнить цикл активного ожидания (busy-wait) его освобождения без вмешательства ядра. Такие циклы подходят только для доступа к тем ресурсам, которые занимаются на короткие промежутки времени, в иных случаях необходимо блокирование нити. Блокирование LWP требует вмешательства ядра и вследствие этого является затратной процедурой.
Каждый легковесный процесс потребляет значительные ресурсы ядра, включая физическую намять, отводимую под стек ядра. По этой причине cистема не может поддерживать большое количество LWP. Более того, так сак система имеет единую реализацию LWP, такие процессы должны область достаточной универсальностью для поддержки наиболее типичных приложений. Таким образом, они могут содержать в себе такие свойства, которые окажутся ненужными большинству приложений. Применение LWP завершенно не подходит для приложений, использующих большое количество нитей или часто создающих и уничтожающих их. Наконец, легковесные процессы должны планироваться на выполнение ядром. Приложения, которым необходимо часто передавать управление от одной нити к другой, не могут 1елать это так легко, используя LWP. Применение легковесных процессов также способно повлечь некоторые неожиданные последствия, например, приложение имеет возможность монополизировать использование процессов а, создав большое количество LWP.
Подводя итоги, скажем, что хотя ядро системы предоставляет механизмы издания, синхронизации и обработки легковесных процессов, за их правильное применение отвечает программист. Многим приложениям больше подлеждит реализация на прикладных нитях, описанных в следующем разделе.