Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Theory 2.Architecture _Unix.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
239.1 Кб
Скачать

6.4. Нити

Нити появились в Unix довольно поздно, но они вошли в требования стандартов POSIX и Single Unix Specifications. Во всех современных клонах ОС Unix имеется механизм нитей, семантика (но не обязательно синтаксис) которого соответствует требованиям стандарта POSIX. В Open Unix 8 реализация нитей выполнена на уровне системной библиотеки нитей, однако потребовала и серьезной перестройки ядра. На уровне ядра работа с нитями поддерживается системными сущностями, называемыми легковесными процессами (light weight process). Нить представляет собой отдельный поток управления с точки зрения программы. Легковесный процесс - отдельный поток управления с точки зрения ОС. Легковесный процесс предоставляет нити собственную среду выполнения, прежде всего - динамическую составляющую системного процесса, то есть стек ядра. Легковесные процессы могут интерпретироваться как виртуальные процессоры, как показано на рисунке 6.2. В каждый момент времени легковесный процесс может выполнять только одну нить, но нити могут сменять друг друга в легковесном процессе.

Рисунок 6.2 Нити и легковесные процессы (ЛВП)

Легковесные процессы подчиняются следующим правилам:

  • с одним процессом может быть связано много легковесных процессов;

  • каждый легковесный процесс разделяет адресное пространство "своего" процесса с другими легковесными процессами в том же процессе;

  • каждый легковесный процесс разделяет с легковесными процессами в том же процессе все ресурсы процесса (файлы, программные каналы и т.п.) и пользуется правами и привилегиями доступа своего процесса;

  • каждый легковесный процесс является единицей планирования в ОС (ниже при описании дисциплины планирования мы везде под "процессом" имеем в виду "легковесный процесс");

  • в мультипроцессорной системе несколько легковесных процессов одного процесса могут выполняться на разных процессорах одновременно (реальный параллелизм);

Нити могут быть мультиплексируемыми и связанными.

Системная библиотека нитей обеспечивает мультиплексирование нитей в пуле легковесных процессов каждого процесса по следующим правилам:

  • легковесный процесс может выбирать и выполнять только одну нить за раз;

  • по прошествии некоторого времени легковесный процесс оставляет текущую нить и выбирает другую;

  • позже оставленная нить может быть выбрана вновь, не обязательно тем же легковесным процессом;

  • в многопроцессорной системе имеется вероятность выполнения нитей с реальным параллелизмом.

Размер пула легковесных процессов называется реальным уровнем параллелизма. Уровень параллелизма устанавливается в конфигурационных параметрах, но может устанавливаться для процесса и программно при помощи соответствующего системного вызова. Кроме того, он может изменяться динамически "вокруг" установленного уровня. Динамическое изменение уровня параллелизма выполняется библиотекой нитей для каждого процесса отдельно. При запуске каждого процесса для него создается только один легковесный процесс. Размер пула увеличивается, если создается новая нить с соответствующим параметром системного вызова thr_create. Если все легковесные процессы данного процесса оказываются в заблокированном состоянии, ядро посылает процессу специальный сигнал. По этому сигналу создается новый легковесный процесс. Как правило, количество легковесных процессов не превосходит количество нитей. Если легковесный процесс остается без работы в течение некоторого предустановленного интервала времени, он прекращается.

Связанная нить имеет собственный легковесный процесс для выполнения. Этот процесс создается одновременно с созданием нити (это определяется специальным параметром системного вызова thr_create) и уничтожается с уничтожением нити. Связанные нити не учитываются при определении реального уровня параллелизма. Связанная нить постоянно присоединена к своему легковесному процессу, когда такая нить переходит в ожидание, ее легковесный процесс также ожидает.

Мультиплексируемые же нити планируются на легковесные процессы - подобно тому, как процессы планируются на процессоры. Дисциплины планирования мультиплексируемых нитей реализуются библиотекой нитей, он "не видны" для ОС. Смена нитей на легковесном процессе происходит по событиям. Событиями, распознаваемыми библиотекой нитей, являются:

  • освобождение легковесного процесса вследствие завершения выполнявшейся на нем нити, перехода нити в состояние ожидания вследствие выполнения ею системного вызова или срабатывания механизмов синхронизации нитей (см. ниже);

  • переход в состояние готовности нити с более высоким приоритетом, чем выполняющаяся;

  • выполнение текущей нитью системного вызова thr_yeld, которым она уступает свой легковесный процесс нити с таким же или более высоким приоритетом - если такие имеются.

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

Приведенное выше описание механизма нитей мы строили на базе ОС Open Unix 8. Подобным же образом этот механизм реализован в ОС Solaris 8. В ОС AIX 5L "легковесные процессы" называются "нитями ядра". В этих ОС также различаются связанные и мультиплексируемые нити.

Однако, ряд клонов реализуют совершенно иной механизм нитей. В ОС FreeBSD нити фактически являются отдельными процессами. В ОС FreeBSD имеется системный вызов rfork, который порождает новый процесс с возможностью управления наследованием ресурсов в новом процессе. Среди ресурсов, определяемых для наследования, может быть и адресное пространство процесса-родителя. Библиотечный вызов rfork_thread позволяет создать на базе вызова rfork нить и запустить в ней заданную процедуру.

Функционально аналогичный системный вызов - clone() - для порождения процессов-потомков с разделением адресного пространства и других (на выбор) ресурсов процесса-родителя существует в ОС Linux. Вызов clone() позволяет задать флаги, указывающие, что порожденный процесс будет иметь со своим предком общие:

  • адресное пространство;

  • информацию о файловой системе: корневой и текущий каталоги;

  • таблицу открытых файлов;

  • таблицу обработчиков сигналов;

  • родителя - в этом случае будет порожден не "дочерний", а "сестринский" процесс.

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

В ОС Tru64 Unix имеется вызов pthread_atfork(), который позволяет определить процедуру, выполняемую в процессе, порождаемом системным вызовом fork().

Помимо пользовательских нитей, почти во всех описанных нами ОС бывают еще нити ядра, порождаемые с помощью вызова kernel_thread() для внутренних системных нужд.