Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
14-19).docx
Скачиваний:
3
Добавлен:
07.09.2019
Размер:
39.24 Кб
Скачать

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.

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]