Windows для профессионалов


Программирование приоритетов


Так как же процесс получает класс приоритета? Очень просто Вызывая CreateProcess, Вы можете указать в ее параметр fdwCreate нужный класс приоритета. Идентифика торы этих классов приведены в следующей таблице.

Класс приоритета Идентификатор
Real-time RFALTIME_PRIORITY_CLASS


High

HIGH_PRIORITY_CLASS
Above normal ABOVE_NORMAL_PRIORITY_CLASS
Normal NORMAL_PRIORITY_CLASS
Below normal BELOW_NORMAL_PRIORITY_CLASS
Idle IDLE_PRIORITY_CLASS

Вам может показаться странным, что, создавая дочерний процесс, родительский сам устанавливает ему класс приоритета. За примером далеко ходить не надо — возь мем все тот же Explorcr При запуске из него какого-нибудь приложения новый про цесс создается с обычным приоритетом Но Explorer ведь не знает, что делает этот процесс и как часто его потокам надо выделять процессорное время. Поэтому в сис теме предусмотрена возможность изменения класса приоритета самим выполняемым процессом — вызовом функции SetPriontyClass-

BOOL SetPriontyClass( HANDLE hProcess, DWORD fdwPriority);

Эта функция меняет класс приоритета процесса, определяемого описателем hPro cess, в соответствии со значением параметра fdwPriority. Последний должен содержать одно из значений, указанных в таблице выше. Поскольку SetPriorityClass принимает описатель процесса, Вы можете изменить приоритет любого процесса, выполняемо го в системе, — если его описатель известен и у Вас есть соответствующие права дос тупа.

Обычно процесс пытается изменить свой класс приоритета. Вот как процесс может сам себе установить класс приоритета idle:

BOOL SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS);

Парная ей функция GetPriorityClass позволяет узнать класс приоритета любого процесса.

DWORD GetPriorityClass(HANDLE hProcess);

Она возвращает, как Вы догадываетесь, один из ранее перечисленных флагов.

При запуске из оболочки командного процессора начальный приоритет програм мы тоже обычный. Однако, запуская ее командой Start, можно указать ключ, опреде ляющий начальный приоритет Так, следующая команда, введенная в оболочке коман дного процессора, заставит систему запустить приложение Calculator и присвоить ему приоритет idle:


C:\>START /LOW CALC.EXE

Команда Start допускает также ключи /BELOWNORMAL, /NORMAL, /ABOVENORMAL, /HIGH и /REALTIME, позволяющие начать выполнение программы с соответствующим классом приоритета. Разумеется, после запуска программа может вызвать SetPriorrty Class и установить себе другой класс приоритета.

WINDOWS 98
В Windows 98 команда Start не поддерживает ни один из этих ключей. Из обо лочки командного процессора Windows 98 процессы всегда запускаются с классом приоритета normal.

Task Manager в Windows 2000 дает возможность изменять класс приоритета про цесса. На рисунке ниже показана вкладка Processes в окне Task Manager co списком выполняемых на данный момент процессов. В колонке Base Pri сообщается класс приоритета каждого процесся Вы можете изменить его, выбрав процесс и указав другой класс в подменю Set Priority контексшого меню.



Только что созданный поток получает относительный приоритет normal Почему CreateThoread не позволяет задать относительный приоритет — для меня так и остает ся загадкой. Такая операция осуществляется вызовом функции:

BOOL SetThreadPriority( HANDLE hThread, int nPriority);

Разумеется, параметр bThread указывает на поток, чей приоритет Вы хотите из менить, а через nPriority передается один из идентификаторов (см. таблицу ниже)

Относительный приоритет потока Идентификатор
Time-critical THREAD_PRIORITY_TIME_CRITICAL
Highest THREAD_PRIORITY_HIGHEST
Above normal THREAD_PRIORITY_ABOVE_NORMAL
Normal THREAD_PRIORITY_NORMAL
Below normal THREAD_PRIORITY_BELOW_NORMAL
Lowest THREAD_PRIORITY_LOWEST
Idle THREAU_PRIORITY_IDLE
Функция GetThreadPnority, парная SetThreadPriority, позволяет узнать относитель ный приоритет потока.

int GetThreadPriority(HANDLE hThread);

Она возвращает один из идентификаторов, показанных в таблице выше.

Чтобы создать поток с относительным приоритетом idle, сделайте, например, так:

DWORD dwThreadID;

HANDLE hThread = CreateThread(NULL, 0, ThreadFunc, NULL, CREATE_SUSPENDED, &dwThreadID); SetThreadPriority(hThread, THREAD_PRIORITY_IDLE); ResumeThread(hThread); CloseHandle(hThread);



Заметьте, что CreateThread всегда создает поток с относительным приоритетом normal. Чтобы присвоить потоку относительный приоритет idle, создайте приоста новленный поток, передав в CreateThread флаг CREATE_SUSPENDED, а потом вызови те SetThreadPriority и установите нужный приоритет. Далее можно вызвать Resume Thread, и поток будет включен в число планируемых. Сказать заранее, когда поток получит процессорное время, нельзя, но планировщик уже учитывает его новый при оритет Выполнив эти операции, Вы можете закрыть описатель потока, чтобы соот ветствующий объект ядра был уничтожен по завершении данного потока.

NOTE:
Ни одна Windows-функция не возвращает уровень приоритета потока. Такая ситуация создана преднамеренно. Вспомните, что Microsoft может в любой момент изменить алгоритм распределения процессорного времени. Поэтому при разработке приложений не стоит опираться на какие-то нюансы этого алгоритма. Используйте классы приоритетов процессов и относительные при оритеты потоков, и Ваши приложения будут нормально работать как в нынеш них, так и в следующих версиях Windows


Содержание раздела