Иллюстрированный самоучитель по Visual Studio.Net


Переключение потоков - часть 3


Представьте такую ситуацию: поток 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 позволяют выяснить текущее состояние флага.

Рис. 12.7. Диапазон изменения приоритета потока

При наличии нескольких процессоров Windows NT применяет симметричную модель распределения потоков по процессорам (symmetric multiprocessing SMP), Это означает, что любой поток может быть направлен на любой процессор, но программист может ввести некоторые коррективы в эту модель равноправного распределения.Функции SetProcessAffinityMask и SetThreadAffinityMask позволяют указать предпочтения в смысле выбора процессора для всех потоков процесса или для одного определенного потока. Потоковое предпочтение (thread affinity) вынуждает систему выбирать процессоры только из множества, указанного в маске. Существует также возможность для каждого потока указать один предпочтительный процессор. Это делается с помощью функции SetThreadidealProcessor. Это указание служит подсказкой для планировщика заданий, но не гарантирует строгого соблюдения.




Начало  Назад  



Книжный магазин