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

ПОТОКИ Концепцию процесса можно охарактеризовать двумя параметрами:

1. Владение ресурсами. Процесс включает виртуальное адресное пространство в котором содержится образ процесса и время от времени может владеть такими ресурсами, как основная память, устройство вв/выв, файлы. ОС выполняет защитные функции предотвращая нежелательные взаимодействия процессов. 2. Планирование и выполнение. Выполнение процесса осуществляется путём выполнения кода прои при этом выполнение процесса может чередоваться с выполнением других процессов. Таким образом процесс имеет такие параметры как состояние и текущий приоритет, в соответствии с которым ОС осуществляет его планирование и диспетчеризацию. В большинстве ОС эти две характеристики являются сущностью процесса. Однако они являются независимыми и ОС может рассматривать их отдельно друг от друга. Чтобы различать эти две характеристики единицу диспетчеризации называют потоком (термин нить, волокно), а единицу владения ресурсами – процессом или задачей. Многопоточностью называется способность ОС поддерживать в рамках одного процесса выполнение нескольких потоков.

Традиционный подход, при котором каждый процесс представляет собой единый поток выполнения называется однопоточным. Например MS-DOS. Реализация потоков в пространстве пользователя Есть два основных способа реализации пакета потоков: в пространстве пользователя и ядре. Выбор между ними остается спорным вопросом, и возможна смешанная реализация. Мы рассмотрим оба способа, а также их преимущества и недостатки. Первый метод состоит в размещении пакета потоков целиком в пространстве пользователя. При этом ядро о потоках ничего не знает и управляет обычными, однопоточными процессами. Наиболее очевидное преимущество этой модели состоит в том, что пакет потоков на уровне пользователя можно реализовать даже в ОС, не поддерживающей потоки. Все ОС когда-то относились к этой категории, а некоторые относятся до сих пор. Подобные реализации имеют в своей основе одинаковую общую схему, представленную на рис. 9, а. Потоки работают поверх системы поддержки исполнения программ, которая является набором процедур, управляющих потоками. С четырьмя из них мы уже знакомы: thread_сreate, thread_exit, thread_wait и thread_yield, но обычно их больше. Рис.Рис. 9. Пакет потоков в пространстве пользователя (а); пакет потоков, управляемый ядром (б) Если управление потоками происходит в пространстве пользователя, каждому процессу необходима собственная таблица потоков для отслеживания потоков в процессе. Эта таблица аналогична таблице процессов, с той лишь разницей, что она отслеживает лишь характеристики потоков, такие как счетчик команд, указатель вершины стека, регистры, состояние и т. п. Когда поток переходит в состояние готовности или блокировки, вся инфа, необходимая для повторного запуска, хранится в таблице потоков подобному тому, как в ядре хранится инфа о процессах в таблице процессов. Когда поток, ожидая окончания действия другого потока в том же процессе, делает нечто, что может привести к локальной блокировке, он вызывает процедуру системы поддержки исполнения программ.

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

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



Наши рекомендации