Структура ОС Windows Подсистема Win32 Объекты ядра Процессы и потоки в ОС Windows Планирование потоков 1 Лекция 4. Управление процессами в ОС Windows NT.

Презентация:



Advertisements
Похожие презентации
Процессы и потоки в ОС Windows :06:23 1 Процесс это просто экземпляр выполняемой программы, включая текущие значения счетчика команд, регистров.
Advertisements

Создание процессов в Windows, часть II BOOL CreateProcess ( LPCTSTR lpApplicationName, // имя исполняемого модуля LPTSTR lpCommandLine, // команда командной.
Объекты ядра Дескрипторы объектов ядра Создание и удаление объектов Свободное (signaled) и занятое (non-signaled) состояния События Мьютексы Семафоры Лекция.
Глава 6. УПРАВЛЯЮЩИЕ СТРУКТУРЫ Оператор присваивания Простой и составной операторы Условный оператор Оператор множественного выбора Оператор цикла с предусловием.
Учебный курс Основы операционных систем Лекция 2 кандидат физико-математических наук, доцент Карпов Владимир Ефимович.
Учебный курс Объектно-ориентированный анализ и программирование Лекция 4 Трансформация логической модели в программный код Лекции читает кандидат технических.
Подпрограммы 1.Принцип модульности 2.Область действия переменных 3.Параметры подпрограмм 4.Модули.
Учебный курс Основы операционных систем Лекция 3 кандидат физико-математических наук, доцент Карпов Владимир Ефимович.
Системы реального времени Лекция 4: процессы. Понятие процесса Процесс - фундаментальное понятие любой операционной системы С помощью процессов происходит.
Операционные системы Подготовила Подготовила студентка студентка 1 курса группы Э курса группы Э-108 Шпудейко Кристина Шпудейко Кристина.
Основы информатики Классы Заикин Олег Сергеевич zaikin.all24.org
Массивы 9 класс. Основные теоретические сведения Примеры решения задач.
Системное программное обеспечение Кыргызско – Российский Славянский Университет Кафедра ИВТ, 3-й курс ИВТ, 5 семестр Лекция 9.
Тема 5. Основы современной технологии программирования Программирование в средах современных информационных систем. Интегрированные системы разработки.
Операционная система. Базовые понятия Операционная система – это комплекс программ, обеспечивающий контроль за существованием, распределением и использованием.
Операционная система MS Windows* Развитие ОС: пакетная обработка, интерактивные системы, ОС реального времени, системы с разделением времени. Истинная.
Раздел 3 Сетевые модели. Тема 3.1 Понятие сетевой модели. Архитектура сети определяет основные элементы сети, характеризует ее общую логическую организацию,
Работа с таблицами в MS Access. Таблицы Единицей хранящейся в БД информации является таблица. Таблица представляет собой совокупность строк и столбцов,
Управление памятью. В ИРТУАЛЬНАЯ ПАМЯТЬ Основная идея заключается в разбиении программы на части, и в память эти части загружаются по очереди. Программа.
Сетевые службы Для конечного пользователя сеть это не компьютеры, кабели и концентраторы и даже не информационные потоки, для него сеть это, прежде всего,
Транксрипт:

Структура ОС Windows Подсистема Win32 Объекты ядра Процессы и потоки в ОС Windows Планирование потоков 1 Лекция 4. Управление процессами в ОС Windows NT :27:47

Структура ОС Windows Объекты ядра :27:47

Структура ОС Windows :27:47 Первые версии системы имели микроядерный дизайн, основанный на микроядре Mach, которое было разработано в университете Карнеги - Меллона. Архитектура более поздних версий системы микроядерной уже не является. Большой объем системного кода ( управление системными вызовами и экранная графика ) был перемещен из адресного пространства пользователя в пространство ядра и работает в привилегированном режиме.

:27:47 4 В результате в ядре ОС Windows переплетены элементы микроядерной архитектуры и элементы монолитного ядра ( комбинированная система ). Основные компоненты ядра Windows NT располагаются в вытесняемой памяти и взаимодействуют друг с другом путем передачи сообщений ( микроядерная архитектура ) В тоже время все компоненты ядра работают в одном адресном пространстве и активно используют общие структуры данных, что свойственно операционным системам с монолитным ядром. Структура ОС Windows

Подсистема Win32 5 ntdll.dll - внутренние функции поддержки и интерфейсы диспетчера системных сервисов с функциями исполнительной системы; hal.dll - уровень абстрагирования от оборудования; win32k.sys - часть подсистемы Win32, работающая в режиме ядра; kernel32.dll, advapi32.dll, user32.dll, gdi32.dll - основные dll подсистемы Win :27:47 Основные компоненты Win32: ntoskrnl.exe - исполнительная система и ядро ; Приложение TextEditorTextEditor Монитор

Системные вызовы в Win :27:47 6 При вызове приложением одной из Win32- функций может возникнуть одна из трех ситуаций : 1)Функция полностью выполняется внутри данной dll ( шаг 1). 2) Для выполнения функции привлекается сервер csrss, для чего ему посылается сообщение (шаг 2a, за которым обычно следуют шаги 2b и 2c). 3) Данный вызов транслируется в системный сервис (системный вызов), который обычно обрабатывается в модуле ntdll.dll (шаги 3a и 3b). Например, Win32-функция ReadFile выполняется с помощью недокументированного сервиса NtReadFile

Объекты ядра 7 Для работы с важными системными ресурсами ОС Windows создает объекты, управление которыми осуществляет менеджер объектов. Ядро поддерживает базовые объекты двух видов : объекты диспетчера ( события, мьютексы, семафоры, потоки ядра, таймеры и др.) и управляющие (DPC, APC, прерывания, процессы, профили и др.) Над объектами ядра находятся объекты исполнительной системы, каждый из которых инкапсулирует один или более объектов ядра. Объекты исполнительной системы предназначены для управления памятью, процессами и межпроцессным обменом. К ним относятся такие объекты, как : процесс, поток, открытый файл, семафор, мьютекс, маркер доступа и ряд других (MSDN). Эти объекты и называются объектами ядра в руководствах по программированию :27:47

Объекты ядра :27:47 8 Внешнее отличие объектов ядра ( объектов исполнительной системы ) от объектов User и GDI состоит в наличии у первых атрибутов защиты, Далее эти объекты ядра ( объекты исполнительной системы ) будут называться просто объектами. Объект представляет собой блок памяти в виртуальном адресном пространстве ядра. Этот блок содержит информацию об объекте в виде структуры данных. Структура содержит как общие, так и специфичные для каждого объекта элементы. Объекты создаются в процессе загрузки и функционирования ОС и теряются при перезагрузке и выключении питания. Содержимое объектов доступно только ядру, приложение не может модифицировать его непосредственно. Доступ к объектам можно осуществить только через его функции - методы ( инкапсуляция данных ), которые инициируются вызовами некоторых библиотечных Win32- функций.

Создание и мониторинг объектов ядра :27:47 9 void __fastcall TForm1::SmCreateClick(TObject *Sender) { try { HANDLE r=CreateSemaphore(NULL,1,5,"MySem"); if (r) {AnsiString msg="Semaphore was created"; LBConsole->Items->Add(msg);} else LBConsole->Items->Add("Error"); } catch (... ) { } } void __fastcall TForm1::SmOpenClick(TObject *Sender) { try {HANDLE r=OpenSemaphore(SEMAPHORE_ALL_ACCESS, false,"MySem"); if (r) { AnsiString msg="Semaphore was opened."; LBConsole->Items->Add(msg); } else LBConsole->Items->Add("Error opended"); } catch (... ) {} } Приложение SemExampleSemExample Приложение WinobjWinobj

Структура объекта. Методы объекта :27:47 10 Каждый объект имеет заголовок с информацией, общей для всех объектов, а также данные, специфичные для объекта. Например, в поле заголовка имеется список процессов, открывших данный объект, и информация о защите, определяющая, кто и как может использовать объект. Счетчик ссылок на объект увеличивается на 1 при открытии объекта и уменьшается на 1 при его закрытии.

Структура объекта. Методы объекта :27:47 11 Квота устанавливает ограничения на объемы ресурсов. Например, по умолчанию лимит на открытые объекты для процесса Множество объектов делится на типы, а у каждого из объектов есть атрибуты, неизменные для объектов данного типа. Ссылка на тип объекта также входит в состав заголовка. В состав компонентов объекта типа входит атрибут методы - указатели на внутренние процедуры для выполнения стандартных операций. Методы вызываются диспетчером объектов при создании и уничтожении объекта, открытии и закрытии описателя объекта, изменении параметров защиты. Система позволяет динамически создавать новые типы объектов. В этом случае предполагается регистрация его методов у диспетчера объектов. Например, метод open вызывается всякий раз, когда создается или открывается объект и создается его новый описатель.

Описатели объектов :27:47 12 Создание новых объектов, или открытие по имени уже существующих, приложение может осуществить при помощи Win32- функций, таких, как CreateFile, CreateSemaphore, OpenSemaphore и т. д. Это библиотечные процедуры, за которыми стоят сервисы Windows и методы объектов. В случае успешного выполнения создается 64- битный описатель в таблице описателей процесса в памяти ядра. На эту таблицу есть ссылка из блока управления процессом EPROCESS SemExample WinObj ProcExp

Описатели объектов :27:47 13 Из 64- х разрядов описателя 29 разрядов используются для ссылки на блок памяти объекта ядра, 3 - для флагов, а оставшиеся 32 - в качестве маски прав доступа. Маска прав доступа формируется на этапе создания или открытия объекта, когда выполняется проверка разрешений. Таким образом, описатель объекта - принадлежность процесса, создавшего этот объект. По умолчанию он не может быть передан другому процессу. Тем не менее, система предоставляет возможность дублирования описателя и передачи его другому процессу специальным образом. Win32- функции, создающие объект, возвращают приложению не сам описатель, а индекс в таблице описателей, то есть малое число : типа 1,2 а не 64- разрядное. Впоследствии это значение передается одной из функций, которая принимает описатель объекта в качестве аргумента. Одной из таких функций является функция CloseHandle, задача которой - закрыть объект.

Создание объектов ядра :27:47 14 Когда процесс инициализируется в первый pa з, таблица описателей еще пуста. Но стоит одному из его потоков вызвать функцию, создающую объект ядра ( например, CreateFtleMapping), как ядро выделяет для этого объекта блок памяти и инициализирует его, далее ядро просматривает таблицу описателей, принадлежащую данному процессу, и отыскивает свободную запись. Вот некоторые функции, создающие объекты ядра : HANDLE CreateThread(…), HANDEE CreateFile(…), HANDLE CreateFileMapping(…), HANDLE CreateSemaphore(…)… Все функции, создающие объекты ядра, возвращают описатели, которые привязаны к конкретному процессу и могут быть использованы в любом потоке данного процесса Значение описателя представляет собой индекс в таблице описателей, принадлежащей процессу, и таким образом идентифицирует место, где хранится информация, связанная с объектом ядра. Вот поэтому при отладке своего приложения и просмотре фактического значения описателя объекта ядра Вы и видите такие малые величины : 1, 2 и т. д. Но помните, что физическое содержимое описателей не задокументировано и может быть изменено.

Защита объектов :27:47 15 Объекты ядра можно защитить дескриптором защиты (security descriptor), который описывает, кто создал объект и кто имеет права на доступ к нему. Дескрипторы защиты обычно используют при написании серверных приложений ; создавая клиентское приложение, Вы можете игнорировать это свойство объектов ядра. Почти все функции, создающие объекты ядра, принимают указатель на структуру SECURITY_ATTRIBUTES как аргумент, например : HANDLE CreateFileMapping( HANDLE hFile. PSECURITY_ATTRIBUTES psa, DWORD flProtect, DWORD dwMaximumSizeHigh, DWORD dwMaximuniSizeLow, PCTSTR pszNarne); Большинство приложений вместо этого аргумента передает NULL и создает объект с защитой по умолчанию. Такая защита подразумевает, что создатель объекта и любой член группы администраторов получают к нему полный доступ, а все прочие к объекту не допускаются

Защита объектов :27:47 16 Вы можете создать и инициализировать структуру SECURITY_ATTRIBUTES, а затем передать ее адрес. Она выглядит так : typedef struct _SECURITY_ATTRIBUTES { DWORD nLength, LPVOID lpSecurityDescriptor; BOOL bInherttHandle; } SECURITY_ATTRIBUTES; Хотя структура называется SECURITY__ATTRIBUTES, лишь один ее элемент имеет отношение к защите lpSecuntyDescriptor. Если надо ограничить доступ к созданному Вами объекту ядра, создайте дескриптор защиты и инициализируйте структуру SECURITY_ATTRIBUTES следующим образом : SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(sa); // используется для выяснения версий sa.lpSecuntyDescriptor = pSD, // адрес инициализированной SD sa.bInheritHandle = FALSE; // наследование объекта HANDLE hFileMapping = CreateFileMapping(INVALID_HANDLE_VALUE, &sa, PAGE_REAOWRITE, 0, 1024, "MyFileMapping");

Закрытие объекта ядра :27:47 17 Независимо от того, как именно Вы создали объект ядра, по окончании работы с ним его нужно закрьпь вызовом CloseHandle: BOOL CloseHandle(HANDLE hobj); Эта функция сначала проверяет таблицу описателей, принадлежащую вызывающему процессу, чтобы убедиться, идентифицирует ли переданный ей индекс ( описатель ) объект, к которому этот процесс действительно имеет доступ. Если переданный индекс правилен, система получает адрес структуры данных объекта и уменьшает в этой структуре счетчик числа пользователей ; как только счетчик обнулится, ядро удалит объект из памяти. Если же описатель невереи, происходит одно из двух. В нормальном режиме выполнения процесса CloseHandle возвращает FALSE, a GetLastError код ERROR_INVALID_HANDLE. Но при выполнении процесса в режиме отладки система просто уведомляет отладчик об ошибке.

Именование объектов. Разделяемые ресурсы :27:47 18 Многие объекты в системе имеют имена. Именование объектов удобно для учета объектов и поиска нужного объекта. Кроме того, знание имени объекта может быть использовано процессом для получения к нему доступа ( совместное использование ресурсов ). Пространство имен объектов организовано в виде древовидной иерархической системы. В качестве нетерминальной вершины дерева используется объект - " каталог объектов ". Каталог включает информацию, необходимую для трансляции имен объектов в указатели на сами объекты. Именование допускают многие ( но не все ) объекты ядра. Например, следующие функции создают именованные объекты ядра HANDLE CreateMutex(… PCTSTR pszName); HANDLE CreateEvent(… PCTSTR pszName); HANDLE CreateSemaphore(… PCTSTR pszName); HANDLE CreateJobObject(…PCTSTR pszName); Последний параметр, pszName, у всех этих функций одинаков. Передавая в нем NULL, Вы создаете безымянный ( анонимный ) объект ядра. В этом случае Вы можете разделять объект между процессами либо через наследование, либо с помощью DuplicateHandle. А чтобы разделять объект по имени, Вы должны присвоить ему какое - нибудь имя. Тогда вместо NULL в параметре pszName нужно передать адрес строки с именем, завершаемой нулевым символом.

Совместное использование объектов :27:47 19 Иногда у приложений возникает необходимость в разделении ресурсов. В ОС Windows обычно это имеет следствием совместное использование объектов, стоящих за этими ресурсами. Наиболее распространенный вариант - когда двум или более процессам известно имя разделяемого объекта. В этом случае один из процессов создает объект ( например, с помощью функции CreateSemaphore), а остальные открывают его для себя ( например, с помощью функции OpenSemaphore).

Процессы и потоки в ОС Windows :27:47 20

Процессы и потоки в ОС Windows :27:47 21 Процесс является динамическим объектом, описывающим выполнение программы. В Windows NT процесс – это объект, создаваемый и уничтожаемый менеджером объектов. Процесс содержит потоки, учетную информацию и ссылки на системные ресурсы : закрытое адресное пространство, семафоры, коммуникационные порты, файлы и т. д. Процесс характеризуется текущим состоянием ( выполнение, ожидание, готовность и т. д.), которые обобществляются всеми потоками процесса. Задача ОС состоит в том, чтобы организовать их поддержку, которая подразумевает, что каждый процесс получит все необходимые ему ресурсы ; Независимые процессы не должны влиять друг на друга, а процессы, которым необходимо обмениваться информацией, должны иметь возможность сделать это путем межпроцессного взаимодействия.

Процессы и потоки в ОС Windows :27:47 22 Для описания процесса ОС поддерживает набор структур, главную из которых принято называть блоком управления процессом (PCB, Process control block). Состав PCB: идентификатор процесса ; токен доступа - исполняемый объект, содержащий информацию о безопасности ; базовый приоритет - основа для исполнительного приоритета нитей процесса ; процессорная совместимость - набор процессоров, на которых могут выполняться нити процесса ; предельные значения квот - максимальное количество страничной и нестраничной системной памяти, дискового пространства, предназначенного для выгрузки страниц, процессорного времени - которые могут быть использованы процессами пользователя ; время исполнения - общее количество времени, в течение которого выполняются все нити процесса.

Внутреннее устройство процессов в ОС Windows :27:47 23 Блок управления процессом (PCB) реализован в виде набора связанных структур, главная из которых называется блоком процесса EPROCESS. ProcExp

Создание процесса :27:47 24 Обычно процесс создается другим процессом вызовом Win32- функции CreateProcess. Создание процесса осуществляется в несколько этапов : 1)на диске отыскивается нужный файл - образ, после чего создается объект " раздел " памяти для проецирования на адресное пространство нового процесса (kernel32.dll); 2)выполняется обращение к системному сервису NtCreateProcess для создания объекта " процесс ". Формируются блоки EPROCESS, KPROCESS и блок переменных окружения PEB. Менеджер процессов инициализирует в блоке процесса маркер доступа ( копируя аналогичный маркер родительского процесса ), идентификатор и другие поля ; 3)создание первичного потока ( сервис NtCreateThread, библиотека kernel32.dll); 4) kernel32.dll посылает подсистеме Win32 сообщение, которое содержит информацию, необходимую для выполнения нового процесса. Данные о процессе и потоке помещаются, в список процессов и список потоков данного процесса, затем устанавливается приоритет процесса, создается структура, используемая частью Win32, которая работает в режиме ядра, и т. д.; 5)запускается первичный поток, для чего формируются его начальный контекст и стек, и выполняется запуск стартовой процедуры потока режима ядра KiThreadStartup. После этого стартовый код из библиотеки C/C++ передает управление функции main() запускаемой программы.

Создание процесса. Функция CreateProcess :27:47 25 BOOL CreateProcess( PCTSTR pszApplicationName, //имя программы; PTSTR pszCommandLine, //параметры командной строки; SECURITY_ATTRIBUTES psaProcess, //атрибуты безопасности процесса; PSECURITY_ATTRIBUTES psaThread, //атрибуты безопасности главного потока; BOOL bInheritHandles, //- если bInheritHandles == TRUE, то созданный процесс (запущенная программа), наследует дескрипторы (handles) запускающей программы; DWORD fdwCreationFlags, //- параметры создания. Здесь можно указать класс приоритета создаваемого процесса и некоторые дополнительные параметры; PVOID pvEnvironment, // - указатель на блок окружения или NULL, тогда используется блок окружения родителя; PCTSTR pszCurDir, // текущая директория или NULL, тогда используется текущая директория родителя; PSTARTUPINFO psiStartInfo, //- указатель на структуру STARTUPINFO, которая определяет положение главного окна; PPROCESS_INFORMATION ppiProcInfo //информация о созданном процессе. );

Создание процесса ( пример ) :27:47 26 #include void main( VOID ) { STARTUPINFO StartupInfo; PROCESS_INFORMATION ProcInfo; TCHAR CommandLine[] = TEXT(format c:"); ZeroMemory( &StartupInfo, sizeof(StartupInfo) ); StartupInfo.cb = sizeof(StartupInfo); ZeroMemory( &ProcInfo, sizeof(ProcInfo) ); if( !CreateProcess( NULL, // Не используется имя модуля CommandLine, // Командная строка NULL, // Дескриптор процесса не наследуется. NULL, // Дескриптор потока не наследуется. FALSE, // Установка описателей наследования 0, // Нет флагов создания процесса NULL, // Блок переменных окружения родит. процесса NULL, // Использовать текущий каталог родит. процесса &StartupInfo, // Указатель на структуру STARTUPINFO. &ProcInfo ) // Указатель на структуру информации о процессе. ) printf( "CreateProcess failed." ); // Ждать окончания дочернего процесса WaitForSingleObject( ProcInfo.hProcess, INFINITE ); // Закрыть описатели процесса и потока CloseHandle( ProcInfo.hProcess ); CloseHandle( ProcInfo.hThread ); } Приложение createprocesscreateprocess

Завершение процесса :27:47 27 Процесс завершается если : Входная функция первичного потока возвратила управление. Один из потоков процесса вызвал функцию ExitProcess. Поток другого процесса вызвал функцию TerminateProcess. Когда процесс завершается, все User- и GDI- объекты, созданные процессом, уничтожаются, объекты ядра закрываются ( если их не использует другой процесс ), адресное пространство процесса уничтожается. Рассмотрим, как это реализуется на практике.

Получение идентификатора процесса :27:47 28 Для получения идентификатора процесса (pid) рассмотрим функцию, которая будет определять PID по имени файла. Для этого необходимо получить snapshot ( снимок ) системных процессов с помощью функции CreateToolhelp32Snapshot(), а затем функциями Process32First() и Process32Next() перебираются все процессы для поиска нужного. Здесь существенную роль играет структура PROCESSENTRY32, которая как раз содержит информацию как об имени файла ( элемент szExeFile), так и об идентификаторе процесса ( элемент th32ProcessID). typedef struct tagPROCESSENTRY32 { DWORD dwSize; // Рамер структуры DWORD cntUsage; // Число ссылк на процесс. Процесс уничтожается, // когда число ссылок становится 0 DWORD th32ProcessID; // Идентификатор процесса DWORD th32DefaultHeapID; // Идентификатор основной кучи DWORD th32ModuleID; // идентификатор модуля DWORD cntThreads; // Число потоков DWORD th32ParentProcessID; // Идентификатор родителя LONG pcPriClassBase; // приоритет по умолчанию DWORD dwFlags; // Зарезервировано CHAR szExeFile[MAX_PATH]; // Собственно имя процесса } PROCESSENTRY32,*PPROCESSENTRY32,*LPPROCESSENTRY32;

Получение идентификатора процесса :27:47 29 procedure TForm1.Button1Click(Sender: TObject); var han : THandle; pi : TProcInfo; // from "tlhelp32" in uses clause sID : string; begin LB.Items.Clear; // Get a snapshot of the system han := CreateToolhelp32Snapshot( TH32CS_SNAPALL, 0 ); if han = 0 then exit; pi:=TProcInfo.Create; pi.ProcStruct.dwSize := sizeof( PROCESSENTRY32 ); if Process32First( han, pi.ProcStruct ) then repeat sID := ExtractFileName( pi.ProcStruct.szExeFile ); while length(sID)

Получение списка окон и классов :27:47 30 procedure TForm1.Button2Click(Sender: TObject); var Wnd: hWnd; buff: array[0..127] of Char; classname : array[ ] of Char; s : string; pc : PAnsiChar; nc : integer; begin LB.Clear; Wnd := GetWindow(Handle, gw_HWndFirst); while Wnd 0 do begin { Не показываем :} if (Wnd Application.Handle) and {- Собственное окно } IsWindowVisible(Wnd) and {- Невидимые окна } (GetWindow(Wnd, gw_Owner) = 0) and {- Дочерние окна } (GetWindowText(Wnd, buff, sizeof(buff)) 0) { Окна без заголовков } then begin GetWindowText(Wnd, buff, sizeof(buff)); nc:=GetClassName(Wnd,pc,1023); s:=StrPas(buff); while length(s)

Жизненный цикл потока :27:47 31 Каждый новый процесс содержит, по крайней мере, один поток Потоки составляют основу планирования Готовность. У нити есть все для выполнения, но не хватает только процессора. Первоочередная готовность (standby). Для каждого процессора системы выбирается одна нить, которая будет выполняться следующей. Выполнение. Как только происходит переключение контекстов, нить переходит в состояние выполнения и находится в нем до тех пор, пока либо ядро не вытеснит ее.

Жизненный цикл потока :27:47 32 Ожидание. Нить по своей инициативе ожидает некоторый объект для того, чтобы синхронизировать свое выполнение ; операционная система ( например, подсистема ввода - вывода ) может ожидать в интересах нити ; подсистема окружения может непосредственно заставить нить приостановить себя. Переходное состояние. Нить готова к выполнению, но ресурсы, которые ей нужны, заняты. Завершение. Когда выполнение нити закончилось, она входит в состояние завершения. Находясь в этом состоянии, нить может быть либо удалена, либо не удалена. Код ядра выполняется в контексте текущего потока. Это означает, что при прерывании, системном вызове и т д., то есть когда процессор переходит в режим ядра и управление передается ОС, переключения на другой поток ( например, системный ) не происходит. Контекст потока при этом сохраняется, поскольку операционная система все же может принять решение о смене характера деятельности и переключении на другой поток. Вследствие этого состояние " Выполнение " разделяют на " Выполнение в режиме пользователя " и " Выполнение в режиме ядра. Поэтому у каждого потока два стека, один работает в режиме ядра, другой - в режиме пользователя. Один и тот же стек не может использоваться и в режиме пользователя, и в режиме ядра. Любой поток может делать все что угодно со своим собственным стеком ( стеком режима пользователя ), в том числе организовывать несколько стеков и переключаться между ними. Поток сам может определять размер своего стека.

Внутреннее устройство потоков :27:47 33 Объект - нить имеет следующие атрибуты : Идентификатор клиента - уникальное значение, которое идентифицирует нить при ее обращении к серверу. Контекст нити - содержит текущее состояние регистров, стеков и индивидуальной области памяти, которая используется подсистемами и библиотеками. Динамический приоритет - значение приоритета нити в данный момент. Базовый приоритет - нижний предел динамического приоритета нити. Процессорная совместимость нитей - перечень типов процессоров, на которых может выполняться нить. Время выполнения нити - суммарное время выполнения нити в пользовательском режиме и в режиме ядра, накопленное за период существования нити. Состояние предупреждения - флаг, который показывает, что нить должна выполнять вызов асинхронной процедуры. Счетчик приостановок - текущее количество приостановок выполнения нити.

Планирование потоков :27:47 34 Выбор текущего потока из нескольких активных потоков, пытающихся получить доступ к процессору называется планированием. Выбранный для выполнения поток работает в течение некоего периода, называемого квантом, по истечении которого поток вытесняетсяПредполагается, что поток не знает, в какой момент он будет вытеснен. Поток также может быть вытеснен даже, если его квант еще не истек. Процедура планирования обычно связана с весьма затратной процедурой диспетчеризации - переключением процессора на новый поток, поэтому планировщик должен заботиться об эффективном использовании процессора. Принадлежность потоков к процессу при планировании не учитывается, то есть единицей планирования в ОС Windows является именно поток. В ОС Windows запуск процедуры планирования вызывается одним из следующих событий. События, связанные с освобождением процессора : (1) Завершение потока (2) Переход потока в состояние готовности в связи с тем, что его квант времени истек (3) Переход потока в состояние ожидания События, в результате которых пополняется или может пополниться очередь потоков в состоянии готовности. (4) Поток вышел из состояния ожидания (5) Поток только что создан (6) Деятельность текущего потока может иметь следствием вывод другого потока из состояния ожидания.

Алгоритмы планирования потоков :27:47 35 В ОС Windows реализовано вытесняющее приоритетное планирование, когда каждому потоку присваивается определенное числовое значение - приоритет, в соответствии с которым ему выделяется процессор. Потоки с одинаковыми приоритетами планируются согласно алгоритму Round Robin ( карусель ). В системе предусмотрено 32 уровня приоритетов. Шестнадцать значений приоритетов (16-31) соответствуют группе приоритетов реального времени, пятнадцать значений (1-15) предназначены для обычных потоков, и значение 0 зарезервировано для системного потока обнуления страниц. Класс приоритета для всех потоков конкретного процесса можно задать с помощью набора констант - параметров функции SetPriorityClass, которые могут иметь следующие значения : реального времени (REALTIME_PRIORITY_CLASS), высокий (HIGH_PRIORITY_CLASS), выше нормы (ABOVE_NORMAL_PRIORITY_CLASS), нормальный (NORMAL_PRIORITY_CLASS), ниже нормы (BELOW_NORMAL_PRIORITY_CLASS) неработающий (IDLE_PRIORITY_CLASS).

Приоритеты потоков :27:47 36 Пользовательские потоки работают с приоритетами от 1 до 15. Устанавливая приоритеты процесса и потока, пользователь может отдавать преимущество тому или иному потоку. Нулевой поток работает в фоновом режиме и съедает все процессорное время, на которое больше никто не претендует. Его работа заключается в обнулении страниц для менеджера памяти. Если и у этого потока нет работы, работает пустой поток. Однако он не является полноценным потоком. Со временем для улучшения производительности системы в базовом алгоритме планирования было сделано несколько усовершенствований. При определенных условиях текущий приоритет пользовательского потока может быть поднят операционной системой выше базового приоритета, но никогда не может быть установлен выше приоритета 15. Для потоков с приоритетами 15 и выше никогда не делается никаких изменений приоритета. Приоритет потока увеличивается : 1) Когда завершается операция ввода - вывода и освобождает ожидающий ее поток, приоритет потока увеличивается, чтобы дать шанс этому потоку быстрее запуститься и снова запустить операцию ввода - вывода. Суть в том, чтобы поддерживать занятость устройств ввода - вывода. Величина, на которую увеличивается приоритет, зависит от устройства ввода - вывода. Как правило, это 1 для диска, 2 для последовательной линии, 6 для клавиатуры и 8 для звуковой карты. 2) Если поток ждал семафора, мьютекса или другого события, то когда он отпускается, к его приоритету прибавляется две единицы, если это поток переднего плана ( то есть процесс, управляющий окном, которому в данный момент направляется ввод с клавиатуры ), и одна единица в противном случае.

Приоритеты потоков :27:47 37 Есть еще один случай, при котором система изменяет приоритеты потоков. Представьте, что два потока работают вместе в задаче типа " производитель - потребитель ". Работа производителя труднее, поэтому он получает более высокий приоритет, например 12, а потребитель получает приоритет 4. В определенный момент производитель заполняет до отказа общий буфер и блокируется на семафоре Прежде чем потребитель снова получит шанс поработать, посторонний процесс с приоритетом 8 приходит в состояние готовности и получает управление. Этот поток сможет работать столько, сколько захочет, так как его приоритет выше приоритета потребителя, а производитель, хоть и с большим приоритетом, заблокирован. При таких условиях производитель никогда снова не получит управления, пока поток с приоритетом 8 не остановится.

Приоритеты потоков :27:47 38 В операционной системе Windows 2000 эта проблема решается при помощи большой кувалды. Система следит, сколько времени прошло с тех пор, когда готовый к работе поток запускался в последний раз. Если какой - либо поток превысит определенный интервал времени, он получает на два кванта времени приоритет 15. Это может помочь разблокировать производителя. После двух квантов прибавка приоритета резко убирается. Вероятно, лучшим решением было бы наказывать потоки, которые полностью используют свои кванты снова и снова. В конце концов, проблему создает не поток, умирающий от голода, а жадный поток. Эта проблема хорошо известна под названием инверсии приоритетов. Классы приоритетов процессов Критичный ко времени Самый высокий Выше нормы Нормаль ный Ниже нормы Самый низкий Неработающ ий Ниже нормы Нормальный Выше нормы Высокий Реального времени