Примечание 2
Примечание 2
Термин foreground обозначает то качество процесса, которое характеризует — его с точки зрения связи с активным окном Windows. Foreground window — это окно, которое в данный момент находится в фокусе и, следовательно, расположено поверх остальных. Это состояние может быть получено как программным способом (вызов функции SetFocus), так и аппаратно (пользователь щелкнул окно).
Плакировщик изменяет класс процесса, связанного с этим окном, так чтобы он был больше или равен классу любого процесса, связанного с background-окном. Класс приоритета вновь восстанавливается при потере процессом статуса foreground. Отметьте, что в Windows NT/2000 пользователь может управлять величиной ускорения всех процессов класса NORMAL_PRIORITY с помощью панели управления (команда System, вкладка Performance, ползунок Boost Application Performance).
Когда окно получает сообщение типа WM_TIMER, WM_LBUTTONDOWN или WM_KEYDOWN, планировщик также ускоряет (boosts) ноток, владеющий этим окном. Существуют еще ситуации, когда планировщик временно повышает уровень приоритета потока. Довольно часто потоки ожидают возможности обратиться к диску. Когда диск освобождается, блокированный поток просыпается и в этот момент система повышает его уровень приоритета. После ускорения потока планировщик постепенно снижает уровень приоритета до базового значения. Уровень снижается на одну единицу после завершения очередного кванта времени. Иногда система инвертирует приоритеты, чтобы разрешить конфликты типа deadlock. Благодаря динамике изменения приоритетов потоки активного процесса вытесняют потоки фонового процесса, а потоки с низким приоритетом все-таки имеют шанс получить управление.
Представьте такую ситуацию: поток 1 с высоким приоритетом вынужден ждать, пока поток 2 с низким приоритетом выполняет код в критической секции. В это же время готов к выполнению поток 3 со средним значением приоритета. Он получает время процессора, а два других потока застревают на неопределенное время, так как поток 2 не в состоянии вытеснить поток 3, а поток 1 помнит, что надо ждать, когда поток 2 выйдет из критической секции. Отметьте, что планировщик не способен провести анализ подобной ситуации и решить проблему. Он видит ситуацию только в свете существования двух готовых (ready) потоков с разными приоритетами.
Windows NT/2000 разрешает эту ситуацию так. Планировщик увеличивает приоритеты готовых потоков на величину, выбранную случайным образом. В нашем примере это приводит к тому, что поток с низким приоритетом получает шанс на время процессора и, в течение, может быть, нескольких квантов закончит выполнение кодов критической секции. Как только это произойдет, поток 1 с высоким приоритетом сразу получит управление и сможет, вытеснив поток 3, начать выполнение кодов критической секции.
Windows 95 разрешит эту ситуацию по-другому. Она определяет факт того, что поток 1 с высоким приоритетом зависит от потока 2 с низким приоритетом, и повышает приоритет второго потока до величины приоритета первого. Это приводит к тому, что поток 3 вытесняется потоком 2 и он, закончив выполнение кодов критической секции, пропускает вперед ждавший поток 1.
В системе Windows NT/2000 программист имеет возможность управлять процессом ускорения потоков с помощью API-функций SetProcessPriorityBoost (все потоки данного процесса) или SetThreadPriorityBoost (данный поток) в пределах, которые обозначены на Рисунок 12.7. Функции GetProcessPriorityBoost и GetThreadPriorityBoost позволяют выяснить текущее состояние флага.