Создание потока

ПОТОКИ

Существуют разные определения термина "поток", в том числе "единица исполнения", "отдельный счетчик команд" или "подлежащая планированию сущность внутри процесса". Хотя каждое из этих определений по сути своей правильно, ни одно из них не является удовлетворительным. Что в точности подразумевается под "единицей исполнения"? Просто нечто, исполняемое процессором?

Поток (Thread) – это независимый путь выполнения внутри процесса, разделяющий вместе с процессом общее адресное пространство, код и глобальные данные.

В то время как процесс — это логическое представление работы, которую должна выполнить ОС, поток отображает одну из, возможно, многих необхо­димых подзадач.

Потоки делят между собой элементы своего процесса:

− Адресное пространство

− Глобальные переменные

− Открытые файлы

− Таймеры

− Семафоры

− Статистическую информацию.

 
 

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

Преимущества использования потоков

1. Упрощение программы в некоторых случаях, за счет использования общего адресного пространства.

2. Быстрота создания потока, по сравнению с процессом, примерно в 100 раз.

3. Повышение производительности самой программы, т.к. есть возможность одновременно выполнять вычисления на процессоре и операцию ввода/вывода. Пример: текстовый редактор с тремя потоками может одновременно взаимодействовать с пользователем, форматировать текст и записывать на диск резервную копию.

 
 

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

В случае А ядро о потоках ничего не знает. Каждому процессу необходима таблица потоков, аналогичная таблице процессов.

Преимущества случая А:

− Такую многопоточность можно реализовать на ядре не поддерживающим многопоточность

− Более быстрое переключение, создание и завершение потоков

− Процесс может иметь собственный алгоритм планирования.

Недостатки случая А:

− Отсутствие прерывания по таймеру внутри одного процесса

− При использовании блокирующего (процесс переводится в режим ожидания, например: чтение с клавиатуры, а данные не поступают) системного запроса все остальные потоки блокируются.

− Сложность реализации

Особенности реализации Windows

Используется четыре понятия:

1. Задание - набор процессов с общими квотами и лимитами

2. Процесс

3. Поток

4. Волокно - облегченный поток, управляемый полностью в пространстве пользователя

В исходном состоянии поток находится в приостановленном состоянии.

Основные составляющие потока в исполнительной системе таковы:

− Уникальный указатель, называемый хэндлом потока.

− Содержимое набора регистров, отображающее состояние процессора.

Два стека: один используется потоком при работе в пользовательском
режиме, а другой — в режиме ядра.

− Собственная область памяти, предназначенная для использования подсистемами, библиотеками периода выполнения и динамически под­ключаемыми библиотеками (DLL).

Регистры, стек и собственная область памяти называются контекстом (context) потока. Фактические данные, составляющие контекст потока, зависят от типа процессора.

Процесс Windows остается безжизненным, пока у него нет потока, который можно направить на выполнение. Если у процесса есть поток, последний может со­здать дополнительные потоки.

При создании потока так же, как и при создании процесса, операционная система генерирует специальную информационную структуру — объект-поток, который содержит (рис.7):

− идентификатор потока,

− данные о правах доступа и приоритете,

− данные о состоянии потока и др.

Создаются и уничтожаются потоки исполнительной системы Windows диспетчером объектов. Диспетчер процессов определяет тело объекта-потока и сервисы, используемые для ра­боты с потоками после их создания. В табл. 3 описаны атрибуты потока.

Как можно заметить, некоторые атрибуты потока напоминают атрибуты объекта. Одни атрибуты, такие как процессорное средство потока и динами­ческий приоритет, фактически усиливают или ослабляют ограничения, задан­ные для процесса в целом. Например, процессорное средство каждого потока — это неполное подмножество (равно или меньше) процессорного средства процесса. Следовательно, можно заставить разные потоки процесса выпол­няться на разных группах процессоров.

Таблица 4

Атрибуты объекта-потока

Атрибут Назначение
Идентификатор клиента Уникальное значение, идентифицирующее поток при вызове им сервера
Контекст потока Набор значений регистров и других непостоянных данных, определяющих состояние выполнения потока
Базовый приоритет Нижний предел динамического приоритета потока
Динамический приоритет Приоритет потока на данный момент
Процессорное сродство потока Набор процессоров, на которых может исполняться поток, (неполное) подмножество процессорного сродства процесса потока
Время выполнения потока Общее время выполнения потока в пользовательском режиме и режиме ядра
Статус оповещения Флаг, указывающий на необходимость отработки потоком асинхронного вызова процедуры (АРС)
Счетчик приостановок Количество приостановок выполнения потока без последующего возобновления
Маркер имперсонации Временный маркер доступа, позволяющий потоку выполнять действия от имени другого процесса (используется подсистемами)
Порт завершения Канал коммуникации между процессами, в который диспетчер процессов посылает сообщение при завершении потока (используется подсистемами)
Код завершения потока Причина завершения потока

Аналогично, каждый поток имеет базовый уровень приоритета, который лежит в диапазоне от двух уровней ниже базового приоритета процесса до двух уровней выше этого приоритета, как показано на рис.8.

На рис.8 показан также динамический приоритет потока, нижней границей которого является базовый приоритет потока, а верхняя зависит от вида работ, исполняемых потоком. Например, если поток обрабатывает поль­зовательский ввод, то ядро Windows поднимает его динамический приоритет; если же он выполняет вычисления, то ядро постепенно снижает его приоритет до базового. Снижая приоритет одного процесса и поднимая приоритет другого, подсистемы могут управлять относительной приоритетностью потоков внут­ри процесса. Базовый приоритет процесса определяет, сколь сильно могут различаться приоритеты потоков процесса и как они соотносятся с приорите­тами потоков других процессов.

 
 

Таким образом, каждый процесс должен иметь, по меньшей мере, один поток.

Создание потока в большей степени напоминает программу для Windows, чем создание процесса. Дело в том, что для создания потока используется функция CreateThread() (аналог WinMain()), одним из аргументов которой является указатель на функцию потока (аналог оконной функции). Для создания потока требуется следующая информация:

- Размер стека потока.

- Атрибуты защиты потока. Для указания установленной по умолчанию защиты в NT/XP/2000 либо в среде Windows 9.x, где защита не поддерживается, можно использовано значение NULL.

- Адрес процедуры, с которой начинается выполнение. Это должна быть функция, которая получает в качестве единственного параметра 32-разрядное значение.

- Дополнительное 32-разрядное значение, которое передается в процедуру потока.

- Флаги, которые, помимо прочего, допускают установку уровня приоритета потока.

- Адрес для хранения идентификатора потока. Идентификатор потока представляет собой уникальное системное значение.

Функция CreateThread(). При вызове этой функции происходит следующее:

- в памяти создаются все необходимые для управления потоком струк­туры (назовем их объектом "поток");

- код завершения потока инициализируется значением STILL_ACTIVE;

- создается структура типа CONTEXT для потока;

- создается стек потока;

- инициализируется регистр - указатель стека в структуре типа CONTEXT так, чтобы он указывал на верхнюю границу стека, а регистр -указатель команд - на точку входа функции потока.

Синтаксис функции следующий.

HANDLE CreateThread (LPSECURITY_ATTRIBUTES lpThreadAttributes,

DWORD dwStackSize,

LPTHREAD_START_ROUTINE lpStartAddress,

LPVOID lpParameter,

DWORD dwCreationFlags,

LPDWORD lpThreadld);

Параметры:

lpThreadAttributes - является указателем на струк­туру типа SECURITY_ATTRIBUTES. В Windows 9x атрибуты безопасности не используются, то обычно этот аргумент равен NULL.

dwStackSize - определяет размер выделяемого по­току стека. Если в качестве этого параметра указан 0, то поток будет иметь стек такого же размера, как и у породившего его потока.

lpStartAddress - собственно и опреде­ляет поток, так как является адресом точки входа функции потока. Функция потока может иметь имя, определяемое программистом, но должна иметь следующий синтаксис

DWORD WINAPI ThreadFunction(LPVOID lpParameter);

Четвертый аргумент – lpParameter - это параметр, передаваемый функции потока. Что и каким образом передается в этом параметре, совершенно неважно. Это могут быть всевозможные данные, которые функция потока может использовать для своей работы.

Если пятый аргумент - dwCreationFlags - равен нулю, то выпол­нение потока начнется немедленно. Если этот аргумент будет равен CREATE_SUSPENDED, то начало выполнение потока будет задержано до определенных событий, например, до вызова функции ResumeThread().

В значение, определяемое последним параметром - lpThreadId - записывается идентификатор созданного потока.

Возвращаемое значение: если выполнение функции выполнено успешно, то возвращается хэндл нового объекта потока.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: