Где проводится профессиональная переподготовка "Системное администрирование Windows"? Что-то я не совсем понял как проводится обучение. |
Управление процессами
Замечание об управлении ресурсами
В этой лекции рассматриваются базовые сведения, связанные с управлением процессами. Многое из содержания этой лекции применимо и к другим системам UNIX, отличным от Solaris. Более глубокие знания об управлении ресурсами именно в Solaris, в частности, об управлении проектами, пулами ресурсов, зонами и контейнерами, можно получить из лекции 6 курса "Системное администрирование ОС Solaris 10". Если вы применяете Solaris на сервере, где много свободных ресурсов, или на обычной рабочей станции, где лишь набираете тексты и строите графики, то применять знания, полученные из настоящей лекции, вы будете, может быть, время от времени, а вот материал из лекции 6 курса "Системное администрирование ОС Solaris 10" скорее пригодится вашим коллегам, имеющим дело с ресурсоемкими задачами большего масштаба.
Замечание о совместимости утилит
Несмотря на то, что Solaris удовлетворяет многочисленным стандартам, некоторые программы в системе (точнее, их возможности и ключи) расходятся со стандартом XPG4. Этот стандарт (The X/Open Portability Guide, Issue 4 – XPG4) представляет собой спецификацию, описывающую программы, заголовки и интерфейсы. В частности, описывается ожидаемое поведения ряда программ UNIX и их ключи.
Что находится в каталоге /usr/bin/xpg4
В тех случаях, когда поведение и ключи программ Solaris расходились со спецификацией XPG4, изначальная версия программы под Solaris не изменялась, вместо этого программа, совместимая с XPG4, с примерно такими же функциональными особенностями и совершенно таким же именем, помещалась в каталог /usr/bin/xpg4. Таким образом, для того, чтобы выбрать, какие программы – оригинальные или XPG4-совместимые вы предпочитаете использовать в своей системе, – достаточно указать первым в переменной среды окружения PATH тот каталог, в котором лежат нужные вам "по умолчанию" программы. Если первым указан каталог /usr/bin, то при вызове команды по ее короткому имени (например, grep ), а не по полному имени файла (например, /usr/bin/xpg4/grep ), будет вызываться /usr/bin/grep – оригинальная программа. Если указать в PATH первым /usr/bin/xpg4, то будет запускаться XPG4-совместимая версия. Помните, что оригинальные программы могут располагаться также в /bin, /usr/ucb and /usr/ccs/bin.
Спецификация XPG4 включает в себя спецификации программ из IEEE Std 1003.2-1992 и IEEE Std 1003.2a-1992 (которые вместе носят название POSIX 2).
Общие сведения о многопоточности
Единицей исполнения в любой операционной системе является процесс. Процесс – это совокупность исполняемого кода, данных, связанных с этим кодом, и информации, необходимой для исполнения этого кода операционной системой. Существуют операционные системы, в которых после запуска одного процесса другой не может быть запущен до тех пор, пока не завершится первый. Такие ОС называются однозадачными и встречаются в современном мире редко. Большинство ОС – многозадачные, т.е. способны обеспечить одновременное исполнение нескольких процессов (как правило, нескольких десятков тысяч).
В многозадачной системе всегда есть планировщик задач – часть ядра ОС, которая передает управление от одного процесса другому в соответствии с алгоритмом переключения. Для определения процесса, которому надо передать управление, используется формула, куда входит приоритет процесса – параметр, который придается любому процессу в системе.
Каждый процесс в большинстве ОС (в частности, Solaris, Linux, других системах UNIX и в современных версиях ОС Windows) исполняется в своем собственном адресном пространстве. Процесс не может обратиться к адресному пространству другого процесса, за исключением специального случая использования разделяемой памяти – механизма межпроцессного взаимодействия, который обеспечивается в некоторых ОС. Это сделано для того, чтобы сбои в работе одного процесса не могли повлиять на остальные процессы в системе. Процессы в многозадачной многопользовательской системе могут принадлежать разным пользователям и выполняются независимо друг от друга.
Когда процесс ждет завершения внешнего по отношению к нему события (обработки прерывания, ввода-вывода и пр.) возникает блокировка – код процесса не исполняется, а сам процесс находится в состоянии ожидания. Процесс может состоять из нескольких логических частей. Скажем, моделирование движения молекул может состоять из вычисления их координат в каждый момент времени, записи этой информации на диск и визуализации на экране. В этом случае приостановка вычислений на время записи информации на диск нежелательна.
На помощь приходит механизм многопоточности: внутри одного процесса создается несколько потоков. Поток (thread) – это тоже исполняемый код, как и процесс, но в отличие от процесса, поток разделяет свое адресное пространство с другими потоками этого же процесса. При программировании многопоточного приложения разработчику приходится самому решать, как именно он будет синхронизировать выполнение нескольких потоков внутри своей программы и как обеспечивать доступ к совместно используемой памяти.
Современные средства разработки предоставляют несколько механизмов синхронизации, например, исключения (mutex), блокировки, семафоры. В Solaris для многопоточного программирования можно использовать библиотеку POSIX threads (libpthreads) или разработанную ранее компанией Sun библиотеку libthreads (она сохраняется в Solaris для совместимости с предыдущими версиями).
Кроме удобного распараллеливания работ внутри одного процесса механизм потоков позволяет повысить производительность: управление большим количеством потоков для ядра проще, чем управление таким же количеством процессов, так как при переключении от одного процесса к другому ядро должно выполнить больше операций, чем при переключении от потока к потоку.
В компьютерах с несколькими процессорами (а также с многоядерными процессорами, некоторые из которых обрабатывают несколько потоков команд одновременно, например, UltraSPARC T2 от Sun – 64 потока) многопоточность позволяет исполнять разные потоки на разных процессорах, что во многих случаях дает значительный прирост производительности.
Реализация многопоточности в Solaris
Задача обеспечения многопоточности сводится к созданию оптимального алгоритма управления потоками. С точки зрения ядра Solaris, поток – это единица диспетчеризации, т.е. именно потоки конкурируют между собой за доступ к ресурсам (прежде всего, к процессору).
Диспетчер (также его иногда называют планировщиком) – это часть ядра, ответственная за переключение между потоками, которое выполняется в соответствии с приоритетами потоков. В Solaris наряду с процессом и потоком вводятся понятия потока пользователя (user thread), потока ядра (kernel thread) и легковесного процесса (LWP, lightweight process). Поток ядра в Solaris – это как раз и есть единица диспетчеризации. Поток ядра описывается в ядре небольшой по размеру структурой ("структурой" в понимании языка С, т.е. набором переменных). Поток ядра может быть связан с легковесным процессом, который, в свою очередь, всегда связан с одним потоком пользователя. Кроме этого, поток ядра может быть инициирован самим ядром, и тогда с ним не связан никакой легковесный процесс. Рисунок 9.1 показывает соотношение потока пользователя, потока ядра и легковесного процесса. На рисунке также указано, как называются структуры, описывающие процесс, поток пользователя, легковесный процесс и поток ядра соответственно.
Такая организация многопоточности введена в Solaris начиная с версии Solaris 10, потому что на современном оборудовании она более выигрышна, чем использованная в предыдущих версиях Solaris. Ранее к одному легковесному процессу могло привязываться несколько потоков пользователя ( рис. 9.2), что усложняло управление процессами на уровне библиотеки потоков libthreads и требовало отдельного планировщика потоков пользователя на уровне процесса. Эта схема была эффективной в течение многих лет, так как затраты процессорного времени на создание нового потока ядра были достаточно высоки. С ростом мощности процессоров, появлением многоядерных процессоров, удешевлением компонент в целом оптимизация управления потоками стала более важной, чем экономия на создании новых потоков ядра.
увеличить изображение
Рис. 9.2. Соотношение между потоками пользователя и потоками ядра в Solaris до версии 9 включительно
Иерархия процессов в Solaris
Процессы делятся на ядро и все остальные процессы. Последние называются пользовательскими процессами. Пользовательский процесс не обязательно запущен неким пользователем, то, что он – "пользовательский", означает исключительно то, что он не является ядром.
Само ядро Solaris представляет собой множество потоков (threads), которые выполняются параллельно. Действительно, у ядра много разных дел, было бы странно, если бы ядро пыталось все делать последовательно, а не параллельно. Термин threads часто переводят как "нить", но мы будем говорить в контексте управления процессами именно о "потоках", понимая под этим "потоки команд", в отличие от "потоков данных", которые будем обсуждать ниже.
Потоки ядра чрезвычайно "легковесные", они обладают лишь маленькими сегментом данных и стэком. Передача управления от одного потока ядра другому не требует изменения базовых адресов виртуальной памяти. Каждый поток ядра имеет свой приоритет и может относиться к определенному классу потоков, в том числе и к классу потоков "реального времени".
Solaris реализует многоуровневую поточную модель. Ее назначение – разделить управление потоками пользовательского уровня и работу ядра. Потоки пользовательского уровня имеют свою схему приоритетов. Их планирование проводится с помощью потока-планировщика. Такой поток создается библиотекой потоков, когда многопоточное приложение компилируется и выполняется. Внутри одного пользовательского процесса могут работать свои потоки, передача управления между которыми осуществляется внутренним планировщиком этого процесса. Благодаря этому многопоточные приложения могут порождать тысячи потоков без существенной загрузки ядра. Оно будет видеть это приложение как один процесс. По сути, ядро не видит пользовательские потоки, пока они не присоединяются к легковесному процессу (lightweight process, LWP), имеющему определенное положение в операционной системе. Поток-планировщик отвечает за отображение пользовательских потоков в легковесный процесс (LWP), который связан с потоком ядра для выполнения процессором. Каждый LWP имеет поток ядра, но необязательно каждый поток ядра имеет LWP. Часть потоков ядра задействованы исключительно операционной системой, поэтому LWP здесь не требуется.