Во время разработки библиотеки NPTL существенное внимание уделялось переписыванию планировщика ядра и проектированию такой модели многопоточности, которая бы позволила эффективно выполнять процессы, состоящие из тысяч отдельных потоков. Последующее тестирование показало, что данная цель была достигнута.

Двухуровневая реализация потоков (M: N, или «многие ко многим»)

Реализация многопоточности вида M: N призвана совместить в себе преимущества моделей 1:1 и M:1 и в то же время устранить их недостатки.

В модели M: N каждый процесс может содержать несколько экземпляров KSE, к каждому из которых может быть привязано несколько потоков. Такая структура позволяет ядру распределять потоки приложения между процессорами, избавляясь от потенциальных проблем с масштабированием, которые присущи приложениям с большим количеством потоков.

Главным недостатком модели типа M: N является ее сложность. Задача планирования потоков ложится как на ядро, так и на библиотеку, работающую на уровне пользователя; эти две сущности должны взаимодействовать между собой и обмениваться информацией. Управление сигналами в соответствии с требованиями стандарта SUSv3 тоже является непростой задачей, если задейстовавать реализацию вида M: N.

Реализация вида M: N изначально рассматривалась в качестве основной для библиотеки NPTL, но была отклонена, так как требовала внесения слишком объемных и, вероятно, излишних изменений в ядро, особенно учитывая способность Linux хорошо масштабироваться при работе с большим количеством экземпляров KSE.

33.5. Разные реализации POSIX-потоков в Linux

Linux предоставляет две основные реализации программного интерфейса Pthreads.

• LinuxThreads. Это первая реализация многопоточности в Linux, разработанная Хавьером Лероем.

NPTL (Native POSIX Threads Library). Это современная реализация многопоточности в Linux, разработанная Ульрихом Дреппером и Инго Молнаром в качестве преемника LinuxThreads. NPTL отличается повышенной производительностью по сравнению с LinuxThreads и более строго следует спецификации Pthreads, описанной в стандарте SUSv3. Поддержка библиотеки NPTL требовала внесения в ядро изменений, которые появились в версии Linux 2.6.

Некоторое время в качестве преемника библиотеки LinuxThreads рассматривали другую реализацию под названием NGPT (Next Generation POSIX Threads — POSIX-потоки следующего поколения), разработанную в компании IBM. Библиотека NGPT использовала модель M: N и демонстрировала существенный прирост в производительности по сравнению с LinuxThreads. Однако разработчики NPTL решили заняться новой реализацией. И это решение себя оправдало, так как модель вида 1:1, на которой основана библиотека NPTL, показывала лучшие результаты, чем NGPT. С выпуском NPTL разработка проекта NGPT была прекращена.

В следующих разделах мы подробно рассмотрим эти две реализации и выделим аспекты, в которых они расходятся с требованиями стандарта SUSv3 для спецификации Pthreads.

На данном этапе стоит отметить, что библиотека LinuxThreads уже считается устаревшей; она не поддерживается в glibc версии 2.4 и выше. Все нововведения, касающиеся потоков, добавляются в библиотеку NPTL.

33.5.1. LinuxThreads

На протяжении многих лет библиотека LinuxThreads была основной реализацией многопоточности в Linux, и ее хватало для написания различных многопоточных приложений. Ниже перечислены ее главные особенности.

• Потоки создаются с помощью вызова clone(), для которого указываются следующие флаги:

CLONE_VM | CLONE_FILES | CLONE_FS | CLONE_SIGHAND

• Это означает, что потоки в LinuxThreads разделяют виртуальную память, файловые дескрипторы, атрибуты файловой системы (umask, корневой и текущий каталог) и действия сигналов. При этом идентификаторы текущего и родительского процессов не разделяются.

• Помимо потоков, создаваемых самим приложением, LinuxThreads создает дополнительный «управляющий» поток, который отвечает за создание и завершение потоков.

• Внутренняя работа LinuxThreads основана на сигналах. Если ядро поддерживает сигналы реального времени (Linux 2.2 и выше), эта библиотека использует первые три из них. В более старых ядрах применяются сигналы SIGUSR1 и SIGUSR2. Сигналы этого вида недоступны на уровне приложения (такой подход приводит к значительным задержкам при выполнении различных операций синхронизации потоков).

Расхождения библиотеки LinuxThreads со спецификацией

LinuxThreads не соответствует спецификации Pthreads из стандарта SUSv3 в целом ряде аспектов (реализация LinuxThreads была ограничена возможностями ядра, доступными на момент ее разработки; она была совместима настолько, насколько это было возможно в тех условиях). Расхождения со спецификацией перечислены в следующем списке.

Перейти на страницу:

Похожие книги