Цель: Определение и изменение приоритетов потоков в операционной системе Windows.
Задачи:
1. Изучение теоретического материала по управлению приоритетами потоков.
2. Составление алгоритма программы.
3. Программная реализация.
Ход работы:
1. Получить у преподавателя собственный вариант задания, который предусматривает распараллеливание работы на несколько потоков с разными уровнями приоритетов.
2. Используя изученные механизмы, разработать программу, реализующую полученное задание с измерением времени работы каждого потока.
3. Написать отчет.
Ход защиты:
1. Продемонстрировать преподавателю программу, запускающую потоки с различными приоритетами.
2. Пояснить работу изученных механизмов по программному коду.
В основе многих алгоритмов планирования процессов лежит концепция приоритетного обслуживания. У потоков изначально известна характеристика – приоритет, на основании которого определяется порядок выполнения потоков. Приоритет – это число, характеризующее степень привилегированности потока при использовании ресурсов вычислительной машины, в том числе (и в первую очередь) времени процессора: чем выше приоритет, тем выше привилегии, а значит, поток меньше времени будет проводить в очередях. Приоритет может выражаться числом. В большинстве ОС, поддерживающих потоки, их приоритет непосредственно связан с приоритетом процесса, в рамках которого выполняется данный поток. Значение приоритета из описателя процесса используется при назначении приоритета потокам этого процесса.
|
|
Во многих ОС предусматривается возможность изменения приоритетов в течение жизни потока. Изменения приоритета могут происходить по инициативе самого потока, когда он обращается с соответствующим вызовом к ОС, или по инициативе пользователя, когда он выполняет соответствующую команду. Кроме того, ОС сама может изменять приоритеты потоков в зависимости от ситуации, складывающейся в системе. В последнем случае приоритеты называются динамическими, в отличие от неизменяемых, фиксированных приоритетов.
В ОС Windows 2000 процессу можно задать класс приоритета.
Поддерживается шесть классов приоритетов: простаивающий (IDLE_PRIORITY_CLASS), когда потоки выполняются, если система не занята другой работой; ниже нормального (BELOW_NORMAL_PRIORITY_CLASS); нормальный (NORMAL_PRIORITY_CLASS), у потоков нет особых требований; выше нормального (ABOVE_NORMAL_PRIORITY_CLASS); высокий (HIGH_PRIORITY_CLASS) – потоки немедленно реагируют на события; реального времени (REALTIME_PRIORITY_CLASS), где потоки тоже немедленно реагируют на события и могут вытеснять даже потоки ОС.
Класс приоритета устанавливается с помощью функции
|
|
BOOL SetPriorityClass (
HANDLE Process,
DWORD Priority);
Например, процесс может поменять свой собственный класс приоритета
SetProrityClass (GetCurrentProcess (),HIGH_PRIORITY_CLASS);
Чтобы узнать класс приоритета можно воспользоваться функцией
DWORD GetPriorityClass (
HANDLE Process);
Выбрав класс приоритета, для процесса, не нужно забывать о потоках. В ОС Windows 2000 поддерживается семь относительных приоритетов потоков: THREAD_PRIORITY_TIME_CRITICAL (уровень приоритета 31 в классе REALTIME и 15 в других); THREAD_PRIORITY_HIGHEST (на два уровня выше для текущего класса, для NORMAL уровень приоритета равен 10); THREAD_PRIORITY_ABOVE_NORMAL (на один уровень выше, для NORMAL уровень приоритета равен 9); THREAD_PRIORITY_NORMAL (обычный приоритет для класса, уровень равен 8); THREAD_PRIORITY_BELOW_NORMAL (на один уровень ниже, для NORMAL уровень приоритета равен 7); THREAD_PRIORITY_LOWEST (на два уровня ниже для текущего класса, для NORMAL уровень приоритета равен 6); THREAD_PRIORITY_IDLE (16 – для REALTIME и 1 в других классах).
Задать относительный приоритет потока можно с помощью функции
BOOL SetThreadPriority (
HANDLE Thread,
int Priority);
Узнать относительный приоритет потока позволяет функция
int GetThreadPriority (
HANDLE Thread);
Следующий фрагмент кода показывает, как создать поток с относительным приоритетом HIGH, а по умолчанию поток создается с приоритетом NORMAL.
DWORD ThreadId;
HANDLE Thread = CreateThread (NULL, 0, ThreadFunction, NULL, CREATE_SUSPENDED, &ThreadId);
SetThreadPriority (Thread, THREAD_PRIORITY_HIGH);
ResumeThread (Thread);
CloseHandle (Thread);
Иногда бывает полезным знать, сколько времени поток затратил на выполнение каких-либо операций. В Windows NT /2000/ XP такая функция есть
BOOL GetThreadTimes (
HANDLE Thread,
PFILETIME Created,
// Время с 01.01.1601 в сотнях нс до создания потока
PFILETIME Exited,
// Время с 01.01.1601 в сотнях нс до завершения потока
PFILETIME Kernel,
// Время в сотнях нс, затраченное потоком на код ОС
PFILETIME User);
// Время в сотнях нс, затраченное потоком на код программы