В компьютерных операционных системах облегченный процесс ( LWP ) является средством достижения многозадачности . В традиционном значении этого термина, используемом в Unix System V и Solaris , LWP работает в пользовательском пространстве поверх одного потока ядра и разделяет свое адресное пространство и системные ресурсы с другими LWP в пределах того же процесса . Несколько потоков пользовательского уровня , управляемых библиотекой потоков, могут быть размещены поверх одного или нескольких LWP, что позволяет выполнять многозадачность на уровне пользователя, что может иметь некоторые преимущества в производительности. [1]
В некоторых операционных системах нет отдельного слоя LWP между потоками ядра и пользовательскими потоками. Это означает, что пользовательские потоки реализуются непосредственно поверх потоков ядра. В этих контекстах термин «легковесный процесс» обычно относится к потокам ядра, а термин «потоки» может относиться к пользовательским потокам. [2] В Linux пользовательские потоки реализуются путем разрешения определенным процессам совместно использовать ресурсы, что иногда приводит к тому, что эти процессы называют «легковесными процессами». [3] [4] Аналогично, в SunOS версии 4 и выше (до Solaris ) «легковесный процесс» относился к пользовательским потокам. [1]
Потоки ядра полностью обрабатываются ядром . Они не должны быть связаны с процессом; ядро может создавать их всякий раз, когда ему нужно выполнить определенную задачу. Потоки ядра не могут выполняться в пользовательском режиме. LWP (в системах, где они являются отдельным слоем) привязываются к потокам ядра и предоставляют контекст на уровне пользователя. Это включает в себя ссылку на общие ресурсы процесса, к которому принадлежит LWP. Когда LWP приостановлен, ему необходимо хранить свои регистры на уровне пользователя до тех пор, пока он не возобновит работу, а базовый поток ядра также должен хранить свои собственные регистры на уровне ядра.
LWP медленнее и дороже в создании, чем пользовательские потоки. Всякий раз, когда создается LWP, сначала должен быть сделан системный вызов для создания соответствующего потока ядра, что приводит к переключению в режим ядра. Эти переключения режимов обычно включают копирование параметров между ядром и пространством пользователя, также ядру могут потребоваться дополнительные шаги для проверки параметров на предмет недопустимого поведения. Переключение контекста между LWP означает, что LWP, который вытесняется, должен сохранить свои регистры, затем перейти в режим ядра, чтобы поток ядра сохранил свои регистры, а LWP, который планируется, должен также отдельно восстановить регистры ядра и пользователя. [1]
По этой причине некоторые библиотеки потоков пользовательского уровня позволяют реализовать несколько пользовательских потоков поверх LWP. Пользовательские потоки могут создаваться, уничтожаться, синхронизироваться и переключаться между ними полностью в пользовательском пространстве без системных вызовов и переходов в режим ядра. Это обеспечивает значительное улучшение производительности во времени создания потоков и переключениях контекста. [1] Однако существуют трудности в реализации планировщика потоков пользовательского уровня, который хорошо работает вместе с ядром.
В то время как библиотека потоков пользователя будет планировать пользовательские потоки, ядро будет планировать базовые LWP. Без координации между ядром и библиотекой потоков ядро может принимать неоптимальные решения по планированию. Кроме того, возможны случаи взаимоблокировки, когда пользовательские потоки, распределенные по нескольким LWP, пытаются получить те же ресурсы, которые используются другим пользовательским потоком, который в данный момент не запущен. [1]
Одним из решений этой проблемы является активация планировщика. Это метод взаимодействия ядра и библиотеки потоков. Ядро уведомляет планировщик библиотеки потоков об определенных событиях (например, когда поток собирается заблокироваться), а библиотека потоков может принять решение о том, какое действие предпринять. Вызов уведомления из ядра называется «upcall».
Библиотека уровня пользователя не контролирует базовый механизм, она только получает уведомления от ядра и планирует пользовательские потоки на доступных LWP, а не процессорах. Затем планировщик ядра решает, как планировать LWP на процессорах. Это означает, что LWP могут рассматриваться библиотекой потоков как «виртуальные процессоры». [5]
Solaris реализовал отдельный слой LWP, начиная с версии 2.2. До версии 9 Solaris допускал отображение «многие ко многим» между LWP и пользовательскими потоками. Однако это было отменено из-за сложностей, которые оно вносило, и улучшений производительности планировщика ядра. [1] [6]
UNIX System V и ее современные производные IRIX , SCO OpenServer , HP-UX и IBM AIX позволяют осуществлять сопоставление «многие ко многим» между пользовательскими потоками и LWP. [5] [7]
NetBSD 5.0 представила новую, масштабируемую модель потоков 1:1. Каждый пользовательский поток (pthread) имеет поток ядра, называемый облегченным процессом (LWP). Внутри ядра и процессы, и потоки реализованы как LWP и обслуживаются планировщиком одинаково. [8]
В AIX термин облегченный процесс обычно относится к потоку ядра.