Наверх Системное программирование
Предыдущий раздел Оглавление Следующий раздел

3.2.3. Реализация потоков в пользовательском пространстве

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

Все эти реализации имеют одну и ту же общую структуру (рис. 3.8, а). Запуск потоков происходит поверх системы поддержки исполнения программ (run-time system), представляющей собой набор процедур, которые управляют потоками.

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

Рис

Рис. 3.8. Набор потоков: а — на
пользовательском уровне; б — на уровне ядра
собственный стек

При совершении потоком каких-нибудь действий, вызывающих его локальную блокировку, он вызывает процедуру системы поддержки исполнения программ. Данная процедура осуществляет проверку потока на возможность перевода в состояние блокировки. Она сохраняет по возможности регистры потока в соответствующие записи таблицы потоков, затем находит поток, который готов к выполнению, и перезагружает регистры сохраненными значениями нового потока. После переключения указателя стека и счетчика команд выполнение ново¬го потока автоматически возобновляется. Если машина получает инструкцию сохранения всех регистров, а последующей инструкцией будет загрузка всех регистров, то полное переключение потока осуществляется всего лишь за несколько инструкций. Переключение потоков, которое осуществляется подобным образом, на порядок быстрее, чем перехват управления ядром. Такое преимущество является достаточно веским аргументом в пользу реализации набора потоков на пользовательском уровне.

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

Но при лучшей производительности реализация потоков на пользова¬тельском уровне имеет и ряд существенных проблем. Самой первой проблемой является вопрос реализации блокирующих системных вызовов. Если, например, некоторый поток считывает информацию перед нажатием какой-нибудь клавиши клавиатуры, то такому потоку невозможно разрешить осуществление системного вызова, так как это приведет к приостановке выполнения всех потоков. При этом работая с блокирующими системными вызовами, довольно трудно достичь главной цели организации потоков, состоящей в возможности использования потоками блокирующих вызовов без оказания влияния на выполнение других потоков.

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

Предыдущий раздел Оглавление Следующий раздел