В ос windows число уровней приоритета потока равно

Рассмотрим, как в Windows осуществляется планирование потоков для их выполнения на центральном процессоре. Также посмотрим на приоритеты процессов и потоков

Рассмотрим, как в системе Windows осуществляется планирование потоков для их выполнения на центральном процессоре. Также посмотрим на приоритеты процессов и потоков.

Планирование потоков в системе

В Windows всегда выполняется хотя бы один поток с самым высоким приоритетом. Если в системе много ядер, то Windows делит все ядра на группы по 64 ядра. Каждому процессу даётся доступ к определённой группе ядер. Следовательно потоки этих процессов могут видеть только свою группу ядер.

Поток выполняется на процессоре определённое время, затем уступает место другому потоку. Кстати, максимальное время на которое поток может занять процессор называется квантом. Причем время кванта можно настроить, выбрав короткие или длинные кванты. Как это сделать, я покажу ниже в этой статье, так что читайте дальше.

Поток может не отработать весь свой квант, так как если другой поток готов к выполнению и имеет более высокий приоритет, то он вытеснит первый поток.

В системе существует планировщик, который и занимается управлением потоками. Именно он решает какой поток будет выполняться на процессоре следующим. Причем планировщик работает в режиме ядра.

Так как процессор постоянно обрабатывает разные, несвязанные между собой потоки, то он должен запоминать на каком результате он остановился выполняя определённый поток. Такое запоминание предыдущего потока и переключение на новый называют – переключением контекста.

Планирование осуществляется на уровне потоков, а не процессов. Например, Процесс_А имеет 10 потоков, а Процесс_Б2 потока. Тогда процессорное время распределился между этими 12 потоками равномерно.

Приоритеты потоков

Планирование потоков полагается на их приоритеты. Windows использует 32 уровня приоритета для потоков от 0 до 31:

  • 16 — 31 — уровни реального времени;
  • 1 — 15 — обычные динамические приоритеты;
  • 0 — зарезервирован для потока обнуления страниц.

Вначале поток получает свой Базовый приоритет, который наследуется от приоритета процесса:

  • реального времени (24),
  • высокий (13),
  • выше среднего (10),
  • обычный (8),
  • ниже среднего (6),
  • низкий (4).

Дальше назначается относительный приоритет который увеличивает или уменьшает приоритет потока:

  • критический по времени (+15),
  • наивысший (+2),
  • выше среднего(+1),
  • обычный (0),
  • ниже среднего (-1),
  • самый низкий (-2),
  • уровень простоя (-15).

После получения базового приоритета и корректировки относительным приоритетом получается динамический приоритет:

Базовый приоритет

Относительный приоритет

Реального времени
(24)
Высокий
(13)
Выше среднего
(10)
Обычный
(8)
Ниже среднего
(6)
Низкий
(4)
Критический по времени
(+15 но не выше 15 если это не поток реального времени и не выше 31 если поток реального времени)
31 15 15 15 15 15
Наивысший (+2) 26 15 12 10 8 6
Выше среднего (+1) 25 14 11 9 7 5
Обычный (0) 24 13 10 8 6 4
Ниже среднего (-1) 23 12 9 7 5 3
Самый низкий (-2) 22 11 8 6 4 2
Уровень простоя
(-15 но не ниже 1 если это не поток реального времени и не ниже 16 если это поток реального времени)
16 1 1 1 1 1

Изменить базовый приоритет процесса можно из “Диспетчера задач” на вкладке “Подробности“, или в “Process Explorer“. Однако, это не поменяет относительный приоритет потока.

Диспетчер задач. Проверка приоритета процесса, запущенного командой «start /low notepad.exe»

Приоритеты отдельных потоков можно посмотреть в программе “Process Explorer“. Но изменять их нет смысла, так как только разработчик данной программы понимает как лучше расставить приоритеты потокам.

Получается что относительный приоритет у потока Notepad.exe равен 2, так как динамический приоритет больше базового на 2.

Состояния потоков

Поток может находиться в следующих состояниях:

  • Готов (Ready) — поток готов к выполнению и ожидает процессор.
  • Готов с отложенным выполнением (Deferred ready) — поток выбран для выполнения на конкретном ядре и ожидает именно это ядро.
  • В повышенной готовности (Standby) — поток выбран следующим для выполнения на конкретном ядре. Как только сможет процессор выполнит переключение контекста на этот поток.
  • Выполнение (Running) — выполняется на процессоре пока не истечет его квант времени, или пока его не вытеснит поток с большем приоритетом.
  • Ожидание (Waiting) — поток ждет каких-то ресурсов.
  • Переходное состояние (Transition) — готов к выполнению, но стек ядра выгружен из памяти, как только стек загрузится в память поток перейдет в состояние Готов.
  • Завершение (Terminated) — поток выполнил свою работу и завершился сам, или его завершили принудительно.
  • Инициализация (Initializated) — состояние при создании потока.

Кванты времени

Как я уже говорил квант времени выполнения потока может быть длинным или коротким. В настольных системах по умолчанию квант времени короткий, чтобы различные приложения быстро уступали друг другу место. В серверных системах по умолчанию длинный квант времени, чтобы серверные службы реже переключали контекст процессора.

Итак, теперь я вам покажу как переключить систему на работу с длинным или коротким квантом.  Длительность кванта времени настраивается тут: “Свойства системы” / “Дополнительные параметры системы” / “Дополнительно” / “Быстродействие” / “Параметры” / “Дополнительно”:

Устройство Windows. Планирование потоков, изображение №7

  • Программ – короткий квант времени;
  • Служб – длинный квант времени.

На серверной системе можно выбрать “программ” если это сервер терминалов или просто настольный компьютер с установленной серверной системой.

На десктопной системе можно выбрать “служб” если вы запускаете какую-то длительную компиляцию или рендерите видео, а потом вернуть обратно в состояние “программ“.

Изменение приоритета планировщиком

Планировщик Windows периодически меняет текущий приоритет потоков. Делается это например для:

  • повышения приоритета, если поток слишком долго ожидает выполнение (предотвращает зависание программы);
  • повышения приоритета, если происходит ввод из пользовательского интерфейса (сокращение времени отклика);
  • повышения приоритета, после завершения операции ввода/вывода (чтобы потоки ждущие ввод/вывод быстрее выполнялись). При ждать могут:
    • диск, cd-rom, параллельный порт, видео — повышение на 1 пункт;
    • сеть, почтовый слот, именованный канал, последовательный порт — повышение на 2 пункта;
    • клавиатура или мышь — повышение на 6 пунктов;
    • звуковая карта — повышение на 8 пунктов.
  • когда поток ожидает ресурс, который занят другим потоком, то система может повысить приоритет потока который занял нужный ресурс, чтобы он быстрее выполнил свою работу и освободил этот ресурс;
  • повышается приоритет у потоков которые на первом плане, а свёрнутые приложения работают с низким приоритетом.

Эксперимент

Позвольте продемонстрировать следующий эксперимент, который покажет как посмотреть за повышением и понижением динамического приоритета:

  1. Запустите программу «Блокнот».
  2. Запустите «Системный монитор».
  3. Щелкните на кнопке панели инструментов «Добавить» (Add Counter).
  4. Выберите объект «Поток» (Thread), а затем выберите счетчик «Текущий приоритет» (Priority Current).
  5. В поле со списком введите «Notepad», а затем щелкните на кнопке «Поиск» (Search).
  6. Найдите строку «Notepad/0». Выберите ее, щелкните на кнопке «Добавить» (Add), а затем щелкните на кнопке «ОК».
  7. Как только вы щелкните мышкой по блокноту, то заметите в Системном мониторе, что приоритет у потока «Блокнот» поднялся до 12, если свернуть блокнот то приоритет вновь упадет до 10.

Поток простоя — idle

К вашему сведению процессор всегда обрабатывает какой-нибудь поток. Когда кажется что процессор ничем не занят, на самом деле запускается специальный поток idle (поток простоя). Притом, на каждое ядро процессора существует свой собственный поток простоя. В общем-то все потоки простоя принадлежат процессу простоя. Поток простоя имеет самый низкий приоритет (1), поэтому выполняется только тогда — когда полезных потоков нет.

Групповое планирование

Планирование потоков на базе потоков отлично работает, но не способно решить задачу равномерного распределения процессорного времени между несколькими пользователями на терминальном сервере. Потому в Windows Server 2012 появился механизм группового планирования.

Термины группового планирования:

  • поколение — период времени, в течении которого отслеживается использование процессора;
  • квота — процессорное время, разрешенное группе на поколение (исчерпание квоты означает, что группа израсходовала весь свой бюджет);
  • вес — относительная важность группы от 1 до 9 (по умолчанию 5);
  • справедливое долевое планирование — вид планирования, при котором потокам исчерпавшим квоту могут выделяться циклы простоя;
  • ранг — приоритет групповой политики, 0 — наивысший, чем больше процессорного времени истратила группа, тем больше будет ранг, и с меньшей вероятностью получит процессорное время (ранг всегда превосходит приоритет) (0 ранг у потоков которые: не входят ни в одну группу, не израсходовали квоту, потоки с приоритетами реального времени).

Где же применяется групповое планирование? Например его использует механизм DFSS для справедливого распределения процессорного времени между сеансами на машине. Этот механизм включается по умолчанию при установке роли служб терминалов.

Помимо DFSS групповое планирование применяется в объектах Jobs (Задания), так мы можем ограничить Задание по % потребления CPU, например задание будет потреблять не больше 20% процессорного времени.


Вернуться к оглавлению

Сводка

Планирование потоков Windows

Имя статьи

Планирование потоков Windows

Описание

Рассмотрим, как в Windows осуществляется планирование потоков для их выполнения на центральном процессоре. Также посмотрим на приоритеты процессов и потоков

Ниже представлена не простая расшифровка доклада с семинара CLRium, а переработанная версия для книги .NET Platform Architecture. Той её части, что относится к потокам.

Потоки и планирование потоков

Что такое поток? Давайте дадим краткое определение. По своей сути поток это:

  • Средство параллельного относительно других потоков исполнения кода;
  • Имеющего общий доступ ко всем ресурсам процесса.

Очень часто часто слышишь такое мнение, что потоки в .NET — они какие-то абсолютно свои. И наши .NET потоки являются чем-то более облегчённым чем есть в Windows. Но на самом деле потоки в .NET являются самыми обычными потоками Windows (хоть Windows thread id и скрыто так, что сложно достать). И если Вас удивляет, почему я буду рассказывать не-.NET вещи в хабе .NET, скажу вам так: если нет понимания этого уровня, можно забыть о хорошем понимании того, как и почему именно так работает код. Почему мы должны ставить volatile, использовать Interlocked и SpinWait. Дальше обычного lock дело не уйдёт. И очень даже зря.

Давайте посмотрим из чего они состоят и как они рождаются. По сути поток — это средство эмуляции параллельного исполнения относительно других потоков. Почему эмуляция? Потому, что поток как бы странно и смело это ни звучало — это чисто программная вещь, которая идёт из операционной системы. А операционная система создаёт этот слой эмуляции для нас. Процессор при этом о потоках ничего не знает вообще.

Задача процессора — просто исполнять код. Поэтому с точки зрения процессора есть только один поток: последовательное исполнение команд. А задача операционной системы каким-либо образом менять поток т.о. чтобы эмулировать несколько потоков.

Поток в физическом понимании

«Но как же так?», — скажите вы, — «во многих магазинах и на различных сайтах я вижу запись «Intel Xeon 8 ядер 16 потоков». Говоря по-правде это — либо скудность в терминологии либо — чисто маркетинговый ход. На самом деле внутри одного большого процессора есть в данном случае 8 ядер и каждое ядро состоит из двух логических процессоров. Такое доступно при наличии в процессоре технологии Hyper-Threading, когда каждое ядро эмулирует поведение двух процессоров (но не потоков). Делается это для повышения производительности, да. Но по большому счёту если нет понимания, на каких потоках идут расчёты, можно получить очень не приятный сценарий, когда код выполняется со скоростью, ниже чем если бы расчёты шли на одном ядре. Именно поэтому раздача ядер идёт +=2 в случае Hyper-Threading. Т.е. пропуская парные ядра.

Технология эта — достаточно спорная: если вы работаете на двух таких псевдо-ядрах (логических процессорах, которые эмулируются технологией Hyper-Threading), которые при этом находятся на одном физическом ядре и работают с одной и той-же памятью, то вы будете постоянно попадать в ситуацию, когда второй логический процессор так же пытается обратиться к данной памяти, создавая блокировку либо попадая в блокировку, т.к. поток, находящийся на первом ядре работает с той же памятью.

Возникает блокировка совместного доступа: хоть и идёт эмуляция двух ядер, на самом-то деле оно одно. Поэтому в наихудшем сценарии эти потоки исполняются по очереди, а не параллельно.

Так если процессор ничего не знает о потоках, как же достигается параллельное исполнение потоков на каждом из его ядер? Как было сказано, поток — средство операционной системы выполнять на одном процессоре несколько задач одновременно. Достигается параллелизм очень быстрым переключением между потоками в течение очень короткого промежутка времени. Последовательно запуская на выполнение код каждого из потоков и делая это достаточно часто, операционная система достигает цели: делает их исполнение псевдопараллельным, но параллельным с точки зрения восприятия человека. Второе обоснование существования потоков — это утверждение, что программа не так часто срывается в математические расчёты. Чаще всего она взаимодействует с окружающим её миром: различным оборудованием. Это и работа с жёстким диском и вывод на экран и работа с клавиатурой и мышью. Поэтому чтобы процессор не простаивал, пока оборудование сделает то, чего хочет от него программа, поток можно на это время установить в состояние блокировки: ожидания сигнала от операционной системы, что оборудование сделало то, что от него просили. Простейший пример этого — вызов метода Console.ReadKey().

Если заглянуть в диспетчер задач Windows 10, то можно заметить, что в данный момент в вашей системе существует около 1,5 тысячи потоков. И если учесть, что квант на десктопе равен 20 мс, а ядер, например, 4, то можно сделать вывод, что каждый поток получает 20 мс работы 1 раз в 7,5 сек… Ну конечно же, нет. Просто почти все потоки чего-то ждут. То ввода пользователя, то изменения ключей реестра… В операционной системе существует очень много причин, чтобы что-либо ждать.

Так что пока одни потоки в блокировке, другие — что-то делают.

Создание потоков

Простейшая функция создания потоков в пользовательском режиме операционной системы — CreateThread. Эта функция создаёт поток в текущем процессе. Вариантов параметризации CreateThread очень много и когда мы вызываем new Thread(), то из нашего .NET кода вызывается данная функция операционной системы.

В эту функцию передаются следующие атрибуты:

1) Необязательная структура с атрибутами безопасности:

  • Дескриптор безопасности (SECURITY_ATTRIBUTES) + признак наследуемости дескриптора.

    В .NET его нет, но можно создать поток через вызов функции операционной системы;

2) Необязательный размер стека:

  • Начальный размер стека, в байтах (система округляет это значение до размера страницы памяти)

    Т.к. за нас размер стека передаёт .NET, нам это делать не нужно. Это необходимо для вызовов методов и поддержки памяти.

3) Указатель на функцию — точка входа нового потоками
4) Необязательный аргумент для передачи данных функции потока.

Из того, что мы не имеем в .NET явно — это структура безопасности с атрибутами безопасности и размер стэка. Размер стэка нас мало интересует, но атрибуты безопасности нас могут заинтересовать, т.к. сталкиваемся мы с ними впервые. Сейчас мы рассмотривать их не будем. Скажу только, что они влияют на возможность изменения информации о потоке средствами операционной системы.

Если мы создаём любым способом: из .NET или же вручную, средствами ОС, мы как итог имеем и ManageThreadId и экземпляр класса Thread.

Также у этой функции есть необязательный флаг: CREATE_SUSPENDED — поток после создания не стартует. Для .NET это поведение по умолчанию.

Помимо всего прочего существует дополнительный метод CreateRemoteThread, который создаёт поток в чужом процессе. Он часто используется для мониторинга состояния чужого процесса (например программа Snoop). Этот метод создаёт в другом процессе поток и там наш поток начинает исполнение. Приложения .NET так же могут заливать свои потоки в чужие процессы, однако тут могут возникнуть проблемы. Первая и самая главная — это отсутствие в целевом потоке .NET runtime. Это значит, что ни одного метод фреймворка там не будет: только WinAPI и то, что вы написали сами. Однако, если там .NET есть, то возникает вторая проблема (которой не было раньше). Это — версия runtime. Необходимо: понять, что там запущено (для этого необходимо импортировать не-.NET методы runtime, которые написаны на C/C++ и разобраться, с чем мы имеем дело). На основании полученной информации подгрузить необходимые версии наших .NET библиотек и каким-то образом передать им управление.

Я бы рекомендовал вам поиграться с задачкой такого рода: вжиться в код любого .NET процесса и вывести куда-либо сообщение об удаче внедрения (например, в файл лога)

Планирование потоков

Для того чтобы понимать, в каком порядке исполнять код различных потоков, необходима организация планирования тих потоков. Ведь система может иметь как одно ядро, так и несколько. Как иметь эмуляцию двух ядер на одном так и не иметь такой эмуляции. На каждом из ядер: железных или же эмулированных необходимо исполнять как один поток, так и несколько. В конце концов система может работать в режиме виртуализации: в облаке, в виртуальной машине, песочнице в рамках другой операционной системы. Поэтому мы в обязательном порядке рассмотрим планирование потоков Windows. Это — настолько важная часть материала по многопоточке, что без его понимания многопоточка не встанет на своё место в нашей голове никоим образом.

Итак, начнём. Организация планирования в операционной системе Windows является: гибридной. С одной стороны моделируются условия вытесняющей многозадачности, когда операционная система сама решает, когда и на основе каких условия вытеснить потоки. С другой стороны — кооперативной многозадачности, когда потоки сами решают, когда они всё сделали и можно переключаться на следующий (UMS планировщик). Режим вытесняющей многозадачности является приоритетным, т.к. решает, что будет исполняться на основе приоритетов. Почему так? Потому что у каждого потока есть свой приоритет и операционная система планирует к исполнению более приоритетные потоки. А вытесняющей потому, что если возникает более приоритетный поток, он вытесняет тот, который сейчас исполнялся. Однако во многих случаях это бы означало, что часть потоков никогда не доберется до исполнения. Поэтому в операционной системе есть много механик, позволяющих потокам, которым необходимо время на исполнение его получить несмотря на свой более низкий по сравнению с остальными, приоритет.

Уровни приоритета

Windows имеет 32 уровня приоритета (0-31)

  • 1 уровень (00 — 00) — это Zero Page Thread;
  • 15 уровней (01 — 15) — обычные динамические приоритеты;
  • 16 уровней (16 — 31) — реального времени.

Самый низкий приоритет имеет Zero Page Thread. Это — специальный поток операционной системы, который обнуляет страницы оперативной памяти, вычищая тем самым данные, которые там находились, но более не нужны, т.к. страница была освобождена. Необходимо это по одной простой причине: когда приложение освобождает память, оно может ненароком отдать кому-то чувствительные данные. Личные данные, пароли, что-то ещё. Поэтому как операционная система так и runtime языков программирования (а у нас — .NET CLR) обнуляют получаемые участки памяти. Если операционная система понимает, что заняться особо нечем: потоки либо стоят в блокировке в ожидании чего-либо либо нет потоков, которые исполняются, то она запускает самый низко приоритетный поток: поток обнуления памяти. Если она не доберется этим потоком до каких-либо участков, не страшно: их обнулят по требованию. Когда их запросят. Но если есть время, почему бы это не сделать заранее?

Продолжая говорить о том, что к нам не относится, стоит отметить приоритеты реального времени, которые когда-то давным-давно таковыми являлись, но быстро потеряли свой статус приоритетов реального времени и от этого статуса осталось лишь название. Другими словами, Real Time приоритеты на самом деле не являются таковыми. Они являются приоритетами с исключительно высоким значением приоритета. Т.е. если операционная система будет по какой-то причине повышать приоритет потока с приоритетом из динамической группы (об этом — позже, но, например, потому, что потоку освободили блокировку) и при этом значение до повышения было равно 15, то повысить приоритет операционная система не сможет: следующее значение равно 16, а оно — из диапазона реального времени. Туда повышать такими вот «твиками» нельзя.

Уровень приоритетов процессов с позиции Windows API.

Приоритеты — штука относительная. И чтобы нам всем было проще в них ориентироваться, были введены некие правила относительности расчетов: во-первых все потоки вообще (от всех приложений) равны для планировщика: планировщик не различает потоки это различных приложений или же одного и того же приложения. Далее, когда программист пишет свою программу, он задаёт приоритет для различных потоков, создавая тем самым модель многопоточности внутри своего приложения. Он прекрасно знает, почему там был выбран пониженный приоритет, а тут — обычный. Внутри приложения всё настроено. Далее, поскольку есть пользователь системы, он также может выстраивать приоритеты для приложений, которые запускаются на этой системе. Например, он может выбрать повышенный приоритет для какого-то расчетного сервиса, отдавая ему тем самым максимум ресурсов. Т.е. уровень приоритета можно задать и у процесса.

Однако, изменение уровня приоритета процесса не меняет относительных приоритетов внутри приложения: их значения сдвигаются, но не меняется внутренняя модель приоритетов: внутри по-прежнему будет поток с пониженным приоритетом и поток — с обычным. Так, как этого хотел разработчик приложения. Как же это работает?

Существует 6 классов приоритетов процессов. Класс приоритетов процессов — это то, относительно чего будут создаваться приоритеты потоков. Все эти классы приоритетов можно увидеть в «Диспетчере задач», при изменении приоритета какого-либо процесса.

Другими словами класс приоритета — это то, относительно чего будут задаваться приоритеты потоков внутри приложения. Чтобы задать точку отсчёта, было введено понятие базового приоритета. Базовый приоритет — это то значение, чем будет являться приоритет потока с типом приоритета Normal:

  • Если процесс создаётся с классом Normal и внутри этого процесса создаётся поток с приоритетом Normal, то его реальный приоритет Normal будет равен 8 (строка №4 в таблице);
  • Если Вы создаёте процесс и у него класс приоритета Above Normal, то базовый приоритет будет равен 10. Это значит, что потоки внутри этого процесса будут создаваться с более повышенным приоритетом: Normal будет равен 10.

Для чего это необходимо? Вы как программисты знаете модель многопоточности, которая у вас присутствует.
Потоков может быть много и вы решаете, что один поток должен быть фоновым, так как он производит вычисления и вам
не столь важно, когда данные станут доступны: важно чтобы поток завершил вычисления (например поток обхода и анализа дерева). Поэтому, вы устанавливаете пониженный приоритет данного потока. Аналогично может сложится ситуация когда необходимо запустить поток с повышенным приоритетом.

Представим, что ваше приложение запускает пользователь и он решает, что ваше приложение потребляет слишком много процессорных ресурсов. Пользователь считает, что ваше приложение не столь важное в системе, как какие-нибудь другие приложения и понижает приоритет вашего приложения до Below Normal. Это означает, что он задаёт базовый приоритет 6 относительно которого будут рассчитываться приоритеты потоков внутри вашего приложения. Но в системе общий приоритет упадёт. Как при этом меняются приоритеты потоков внутри приложения?

Таблица 3

Normal остаётся на уровне +0 относительно уровня базового приоритета процесса. Below normal — это (-1) относительно уровня базового. Т.е. в нашем примере с понижением уровня приоритета процесса до класса Below Normal приоритет потока ‘Below Normal’ пересчитается и будет не 8 - 1 = 7 (каким он был при классе Normal), а 6 - 1 = 5. Lowest (-2) станет равным 4.

Idle и Time Critical — это уровни насыщения (-15 и +15). Почему Normal — это 0 и относительно него всего два шага: -2, -1, +1 и +2? Легко провести параллель с обучением. Мы ходим в школу, получаем оценки наших знаний (5,4,3,2,1) и нам понятно, что это за оценки: 5 — молодец, 4 — хорошо, 3 — вообще не постарался, 2 — это не делал ни чего, а 1 — это то, что можно исправить потом на 4. Но если у нас вводится 10-ти бальная система оценок (или что вообще ужас — 100-бальная), то возникает неясность: что такое 9 баллов или 7? Как понять, что вам поставили 3 или 4?

Тоже самое и с приоритетами. У нас есть Normal. Дальше, относительно Normal у нас есть чуть повыше
Normal (Normal above), чуть пониже Normal (Normal below). Также есть шаг на два вверх
или на два вниз (Higest и Lowest). Нам, поверьте, нет никакой необходимости в более подробной градации. Единственное, очень редко, может раз в жизни, нам понадобится сказать: выше чем любой приоритет в системе. Тогда мы выставляем уровень Time Critical. Либо наоборот: это надо делать, когда во всей системе делать нечего. Тогда мы выставляем уровень Idle. Это значения — так называемые уровни насыщения.

Как рассчитываются уровни приоритета?

У нас бал класс приоритета процесса Normal (Таблица 3) и приоритет потоков Normal — это 8. Если процесс Above Normal то поток Normal получается равен 9. Если же процесс выставлен в Higest, то поток Normal получается равен 10.

Поскольку для планировщика потоков Windows все потоки процессов равнозначны, то:

  • Для процесса класса Normal и потока Above-Normal
  • Для процесса класса Higest и потока Normal
    конечные приоритеты будут одинаковыми и равны 10.

Если мы имеем два процесса: один с приоритетом Normal, а второй — с приоритетом Higest, но при этом
первый имел поток Higest а второй Normal, то система их приоритеты будет рассматривать как одинаковые.

Как уже обсуждалось, группа приоритетов Real-Time на самом деле не является таковой, поскольку настоящий Real-Time — это гарантированная доставка сообщения за определённое время либо обработка его получения. Т.е., другими словами, если на конкретном ядре есть такой поток, других там быть не должно. Однако это ведь не так: система может решить, что низко приоритетный поток давно не работал и дать ему время, отключив real-time. Вернее его назвать классом приоритетов который работает над обычными приоритетами и куда обычные приоритеты не могут уйти, попав под ситуации, когда Windows временно повышает им приоритет.

Но так как поток повышенным приоритетом исполняется только один на группе ядер, то получается,
что если у вас даже Real-Time потоки, не факт, что им будет выделено время.

Если перевести в графический вид, то можно заметить, что классы приоритетов пересекаются. Например, существует пересечение Above-Normal Normal Below-Normal (столбик с квадратиками):

Это значит, что для этих трех классов приоритетов процессов существуют такие приоритеты потоков внутри этих классов, что реальный приоритет будет равен. При этом, когда вы задаёте приоритет процессу вы просто повышаете или понижаете все его внутренние приоритеты потоков на определённое значение (см. Таблица 3).

Поэтому, когда процессу выдаётся более высокий класс приоритета, это повышает приоритет потоков процесса относительно обычных – с классом Normal.

Кстати говоря, мы стартовали продажи на CLRium #7, в котором мы с огромным удовольствием будем говорить про практику работы с многопоточным кодом. Будут и домашние задания и даже возможность работы с личным ментором.

Загляните к нам на сайт: мы сильно постарались, чтобы его было интересно изучить.

Давайте поговорим о приоритетах Windows процессов. В большинстве случаев «играться» с настройкой приоритетов нет необходимости, но, иногда, грамотный системный администратор может помочь системе более правильно распределить процессорное время между запущенными задачами. Единого рецепта нет, но путем «подбора и перебора» это вполне реализуемо. Где это может понадобиться? Например, в связке 1С-SQL можно дать больше процессорного времени 1С и SQL, как наиболее критичным к ресурсам процессам.

В общем случае, посмотреть и изменить приоритет запущенного процесса можно через Task Manager

Windows NT/2000/7/2008

Приоритете процессов в диспетчере задачВ Windows 2012 это “закопали» чуть глубже

Windows 2012 изменить приоритет процессовКак видно из приведенных примеров, вам доступно всего 6 приоритетов (как выяснится позже, это классы приоритетов). Достаточно? Microsoft считает, что да. Но давайте вспомним «легендарную» фразу Билла Гейста, который сказал, что «640 KB of RAM will be enough for everybody”. Но время показало, что это далеко не так. : )

А теперь давайте разберемся, как это есть на самом деле.

На самом деле в Windows существует 32 уровня приоритета, от 0 до 31.

Они группируются так:

  • 31 — 16 уровни реального времени;
  • 15 — 1 динамические уровни;
  • 0 — системный уровень, зарезервированный для потока обнуления страниц (zero-page thread).

При создании процесса, ему назначается один из шести классов приоритетов:

  1. Real time class (значение 24),
  2. High class (значение 13),
  3. Above normal class (значение 10),
  4. Normal class (значение 8),
  5. Below normal class (значение 6),
  6. или Idle class (значение 4).

Посмотреть приоритет процесса, как писалось выше, можно, используя Task Manager.

Примечание: Приоритеты Above normal и Below normal появились, начиная с Windows 2000.

Приоритет каждого потока (базовый приоритет потока) складывается из приоритета его процесса и относительного приоритета самого потока. Есть семь относительных приоритетов потоков:

  1. Normal: такой же как и у процесса;
  2. Above normal: +1 к приоритету процесса;
  3. Below normal: -1;
  4. Highest: +2;
  5. Lowest: -2;
  6. Time critical: устанавливает базовый приоритет потока для Real time класса в 31, для остальных классов в 15.
  7. Idle: устанавливает базовый приоритет потока для Real time класса в 16, для остальных классов в 1.

В следующей таблице показаны приоритеты процесса, относительный и базовый приоритеты потока.

Приоритет потока Класс процесса Класс процесса
Idle class Below normal class Normal class Above normal class High class Real time class
1 Idle Idle Idle Idle Idle
2 Lowest
3 Below …
4 Idle class Normal Lowest
5 Above … Below …
6 Below normal class Highest Normal Lowest
7 Above … Below …
8 Normal class Highest Normal Lowest
9 Above … Below …
10 Above normal class Highest Normal
11 Above … Lowest
12 Highest Below …
13 High class Normal
14 Above …
15 Highest
15 Time critical Time critical Time critical Time critical Time critical
16 Idle
17
18
19
20
21
22 Lowest
23 Below …
24 Real time class Normal
25 Above …
26 Highest
27
28
29
30
31 Time critical

Теперь, когда мы все это узнали, что же с этим всем можно сделать? Ну, например, начать использовать.

Как еще можно запустить процесс с «нестандартным» приоритетом или изменить?

Метод 1. Запустить задачу/процесс и изменить приоритет через Task Manager.

Минусы метода:

  • Доступно только 6 приоритетов
  • Переключение приоритетов производится мышкой, не автоматизируется.

Метод 2. Можно воспользоваться командой START с соответствующими ключами

Доступные ключи, отвечающие за приоритеты, следующие (я умышленно опускаю ключи командной строки команды START не имеющие отношения к описываемому процессу работы с приоритетами):

C:>start /?
Starts a separate window to run a specified program or command.
START ["title"] [/D path] [/I] [/MIN] [/MAX] [/SEPARATE | /SHARED]
[/LOW | /NORMAL | /HIGH | /REALTIME | /ABOVENORMAL | /BELOWNORMAL]
[/NODE <NUMA node>] [/AFFINITY <hex affinity mask>] [/WAIT] [/B]
[command/program] [parameters]
LOW       Start application in the IDLE priority class.
NORMAL     Start application in the NORMAL priority class.
HIGH       Start application in the HIGH priority class.
REALTIME   Start application in the REALTIME priority class.
ABOVENORMAL Start application in the ABOVENORMAL priority class.
BELOWNORMAL Start application in the BELOWNORMAL priority class.

Как видим, команда START дает возможность запустить процесс все с теми же 6-ю приоритетами, которые доступны через Task Manager

Минус метода:

  • Доступно только 6 приоритетов

Метод 3. Использование утилиты wmic.exe

Как было показано выше, Task Manager, и команда START достаточно неуклюжи для задачи назначения приоритетов. Посмотрим, как это применять более гибко. Будем использовать утилиту wmic.exe.

Командная строка:

wmic process where name="AppName" CALL setpriority ProcessIDLevel

Пример:

wmic process where name="calc.exe" CALL setpriority 32768

или

wmic process where name="calc.exe" CALL setpriority "above normal"

Приоритеты (предопределенные):

  • idle: 64
  • below normal: 16384
  • normal: 32
  • above normal: 32768
  • high priority: 128
  • real time: 256

Отступление. Что делать если существует несколько одноименных процессов? Приоритет процесса можно менять как по имени процесса, так и с использованием PID (Process ID) процесса.

Вот короткий пример запуска wmic.exe для получения необходимой информации

Используем команду:

wmic process list brief

Примечание: пример выполнения этой команды приводить не буду. Слишком большой список процессов получается. Сделаете это самостоятельно, при желании.

Вы получите список процессов, запущенных на вашем локальном компьютере. Теперь выполните команду:

wmic process list brief | find "cmd.exe"

Результат:

wmic process list brief Специально запустил несколько копий cmd.exe, чтобы иллюстрация была более полной.

Теперь список процессов ограничен только теми процессами, в имени исполняемого модуля которых присутствует строка «cmd.exe». Обратите внимание на PID процесса(ов).

Теперь давайте попробуем отобрать интересующие нас процессы, используя непосредственно WMI и не прибегая к стандартным средствам командной строки. Для этого просто напишите:

wmic process where description='cmd.exe' list brief

Результат:

wmic получаем информацию о процессахСравните полученные результаты. Запомните PID процесса CMD.EXE.

Командная строка для запуска wmic.exe

wmic process where processid='XXXX' CALL setpriority ProcessIDLevel

Ну а теперь можем изменить приоритет конкретного процесса (например с PID=8476):

wmic process where processid='8476' CALL setpriority 32768

или

wmic process where processid='8476' CALL setpriority "above normal"

А что дальше? Прикидывать, пробовать, подбирать и тонко регулировать приоритеты. Улучшая работу сервисов и процессов, а также работу конечных пользователей.

Понятие приоритета
потока.

Поток получает
доступ к процессору на 20 мс, после чего
планировщик переключает процессор на
выполнение другого потока. Так происходит,
только если у всех потоков один приоритет,
но на самом деле в системе существуют
потоки с разными приоритетами, а это
меняет порядок распределения процессорного
времени.

Каждому потоку
присваивается уровень приоритета – от
0 (самый низкий) до 31 (самый высокий).
Решая, какому потоку выделить процессорное
время, система сначала рассматривает
только потоки с приоритетом 31 и подключает
их к процессору по принципу карусели.
Пока в системе имеются планируемые
потоки с приоритетом 31, ни один поток с
более низким приоритетом процессорного
времени не получает. Такая ситуация
называется «голоданием* (starvation). Она
наблюдается, когда потоки с более высоким
приоритетом так интенсивно используют
процессорное время, что остальные
практически не работают. Вероятность
этой ситуации намного ниже в
многопроцессорных системах, где потоки
с приоритетами 31 и 30 могут выполняться
одновременно. Система всегда старается,
чтобы процессоры были загружены работой,
и они простаивают только в отсутствие
планируемых потоков.

Потоки с более
высоким приоритетом всегда вытесняют
потоки с более низким приоритетом
независимо от того, исполняются последние
или нет. Допустим, процессор исполняет
поток с приоритетом 5, и тут система
обнаруживает, что поток с более высоким
приоритетом готов к выполнению. Система
остановит поток с более низким приоритетом
– даже если не истек отведенный ему
квант процессорного времени – и подключит
к процессору поток с более высоким
приоритетом.

При загрузке
системы создается особый поток – поток
обнуления страниц (zero page thread), которому
присваивается нулевой уровень приоритета.
Ни один поток, кроме этого, не может
иметь нулевой уровень приоритета. Он
обнуляет свободные страницы в оперативной
памяти при отсутствии других потоков,
требующих внимания со стороны системы.

Классы приоритета
процессов.

Windows поддерживает
шесть классов приоритета:

  • idle(простаивающий),

  • belownormal (ниже
    обычного),

  • normal(обычный),

  • abovenormal (выше
    обычного),

  • high(высокий),

  • realtime(реального
    времени).

Самый распространенный
класс приоритета – normal, его использует
99% приложений.

Real-lime.Потоки
в этом процессе обязаны немедленно
реагировать на события, обеспечивая
выполнение критических по времени
задач. Такие потоки вытесняют даже
компоненты операционной системы.

High.Потоки в
этом процессе тоже должны немедленно
реагировать на события, обеспечивая
выполнение критических по времени
задач.

Above normal. Класс
приоритета, промежуточный между normal и
high. Это новый класс, введенный в Windows
2000.

Normal.Потоки в
этом процессе не предъявляют особых
требований к выделению им процессорного
времени.

Below normal.Класс
приоритета, промежуточный между normal и
idle. Это новый класс, введенный в Windows
2000.

Idle.Потоки в
этом процессе выполняются, когда система
не занята другой работой. Этот класс
приоритета обычно используется для
утилит, работающих в фоновом режиме,
экранных заставок и приложений, собирающих
статистическую информацию.

Относительный
приоритет потока.

Могут быть следующие
относительные приоритеты потока.

Time-critical.Поток
выполняется с приоритетом 31 в классе
real-time и с приоритетом 15 в других классах.

Highest.Поток
выполняется с приоритетом на два уровня
выше обычною для данного класса.

Above normal.Поток
выполняется с приоритетом на один
уровень выше обычного для данного
класса.

Normal.Поток
выполняется с обычным приоритетом
процесса для данного класса.

Below normal.Поток
выполняется с приоритетом на один
уровень ниже обычного для данного
класса.

Lowest.Поток
выполняется с приоритетом на два уровня
ниже обычного для данного класса

Idle.Поток
выполняется с приоритетом 16 в классе
real-time и с приоритетом 1 в других классах

Таким образом,
можно изменять относительные приоритеты
потоков в пределах процесса. Уровень
приоритета формируется самой системой,
исходя из класса приоритета процесса
и относительного приоритета потока.

В системе
предусмотрена возможность изменения
класса приоритета самим выполняемым
процессом – вызовом функции
SetPriorityClass:

BOOL
SetPriontyClass(
HANDLE hProcess,
DWORD fdwPriority);

Эта функция меняет
класс приоритета процесса, определяемого
описателем hProcess, в соответствии со
значением параметраfdwPriority.

Динамическое
изменение уровня приоритета потока.

Уровень приоритета,
получаемый комбинацией относительного
приоритета потока и класса приоритета
процесса, которому принадлежит данный
поток, называют базовым уровнем приоритета
потока. Иногда система изменяет уровень
приоритета потока. Обычно это происходит
в ответ на некоторые события, связанные
с вводом выводом (например, на появление
оконных сообщений или чтение с диска).

Система повышает
приоритет только тех потоков, базовый
уровень которых находится в пределах
1-15 Именно поэтому данный диапазон
называется «областью динамического
приоритета» (dynamic priority range). Система не
допускает динамического повышения
приоритета потока до уровней реального
времени (более 15) Поскольку потоки с
такими уровнями обслуживают системные
функции, это ограничение не дает
приложению нарушить работу операционной
системы.

Для отключения
механизма динамического изменения
приоритета есть две функции:

BOOL
SetProcessPriorityBoost(
HANDLE hProcess,
BOOL DisablePriontyBoost);

BOOL
SetThreadPriorityBoost(
HANDLE hThread,
BOOL DisablePriorityBoost);

SetProcessPriorityBoostзаставляет систему включить или отключить
изменение приоритетов всех потоков в
указанном процессе, aSetThreadPriorityBoostдействует применительно к отдельным
потокам. Эти функции имеют свои аналоги,
позволяющие определять, разрешено или
запрещено изменение приоритетов:

BOOL
GetProcessPriorityBoost(
HANDLE hProcess,

PBOOL
pDisablePriorityBoost);

BOOL
GeLThreadPriorityBoost(
HANDLE hThread,

PBOOL
pDisablePriorityBoost);

Каждой из этих
двух функций передаётся описатель
нужного процесса или потока и адрес
переменной чипа BOOL, в которой и возвращается
результат.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]

  • #
  • #
  • #
  • #
  • #
  • #
  • #

    11.05.201529.07 Mб44Matlab.djvu

  • #
  • #
  • #
  • #

ВикиЧтение

Системное программирование в среде Windows
Харт Джонсон М

Приоритеты процессов и потоков и планирование выполнения

Приоритеты процессов и потоков и планирование выполнения

Ядро Windows всегда запускает тот из потоков, готовых к выполнению, который обладает наивысшим приоритетом. Поток не является готовым к выполнению, если он находится в состоянии ожидания, приостановлен или блокирован по той или иной причине.

Потоки получают приоритеты на базе классов приоритета своих процессов. Как обсуждалось в главе б, первоначально функцией CreateProcess устанавливаются четыре класса приоритета, каждый из которых имеет базовый приоритет (base priority):

• IDLE_PRIORITY_CLASS, базовый приоритет 4.

• NORMAL_PRIORITY_CLASS, базовый приоритет 9 или 7.

• HIGH_PRIORITY_CLASS, базовый приоритет 13.

• REALTIME_PRIORITY_CLASS, базовый приоритет 24.

Оба предельных класса используются редко, и в большинстве случаев можно обойтись нормальным (normal) классом. Windows NT (все версии) не является ОС реального времени (real-time), чего нельзя сказать, например, о Windows СЕ, и в случаях, аналогичных последнему, классом REALTIME_PRIORITY_CLASS следует пользоваться с осторожностью, чтобы не допустить вытеснения других процессов. Нормальный базовый приоритет равен 9, если фокус ввода с клавиатуры находится в окне; в противном случае этот приоритет равен 7.

Один процесс может изменить или установить свой собственный приоритет или приоритет другого процесса, если это разрешено атрибутами защиты. 

BOOL SetPriorityClass(HANDLE hProcess, DWORD dwPriority)

DWORD GetPriorityClass(HANDLE hProcess)

Приоритеты потоков устанавливаются относительно базового приоритета процесса, и во время создания потока его приоритет устанавливается равным приоритету процесса. Приоритеты потоков могут принимать значения в интервале ±2 относительно базового приоритета процесса. Результирующим пяти значениям приоритета присвоены следующие символические имена:

• THREAD_PRIORITY_LOWEST

• THREAD_PRIORITY_BELOW_NORMAL

• THREAD_PRIORITY_NORMAL

• THREAD_PRIORITY_HIGHEST 

Для установки и выборки относительного приоритета потока следует использовать эти значения. Обратите внимание на использование целых чисел со знаком вместо чисел типа DWORD. 

BOOL SetThreadPriority(HANDLE hThread, int nPriority)

int GetThreadPriority(HANDLE hThread) 

Существуют два дополнительных значения приоритета потоков. Они являются абсолютными, а не относительными, и используются только в специальных случаях.

• THREAD_PRIORITY_IDLE имеет значение 1 (или 16 — для процессов, выполняющихся в режиме реального времени).

• THREAD_PRIORITY_TIME_CRITICAL имеет значение 15 (или 31 — для процессов, выполняющихся в режиме реального времени).

Приоритеты потоков автоматически изменяются при изменении приоритета процесса. Помимо этого, ОС может регулировать приоритеты потоков динамическим путем на основании поведения потоков. Вы можете активизировать или отключить это средство с помощью функции SetThreadPriorityBoost.

Читайте также

Обработчики завершения: завершение процессов и потоков

Обработчики завершения: завершение процессов и потоков
Обработчики завершения не выполняются, если выполнение процесса или потока было прекращено независимо от того, было ли это инициировано самим процессом путем использования функций ExitProcess или ExitThread, или вызвано

ГЛАВА 7 Потоки и планирование выполнения

ГЛАВА 7
Потоки и планирование выполнения
Основной единицей выполнения в Windows является поток, и одновременно несколько потоков могут выполняться в рамках одного процесса, разделяя его адресное пространство и другие ресурсы. В главе 6 процессы ограничивались только одним

Предостережение относительно использования приоритетов потоков и процессов

Предостережение относительно использования приоритетов потоков и процессов
Высокими приоритетами потоков и высокими классами приоритета процессов необходимо пользоваться с осторожностью. Следует решительно избегать использования приоритетов реального времени для

Безопасная отмена выполнения потоков

Безопасная отмена выполнения потоков
Обсуждение предыдущего примера продемонстрировало, как безопасно отменить выполнение целевого потока, который использует состояния дежурного ожидания. Несмотря на использование АРС, такую отмену выполнения иногда называют

Стеки потоков и допустимые количества потоков

Стеки потоков и допустимые количества потоков
Следует сделать еще два предостережения. Во-первых, подумайте о размере стека, который по умолчанию составляет 1 Мбайт. В большинстве случаев этого будет вполне достаточно, но если существуют какие-либо сомнения на сей счет,

Глава 4 Планирование выполнения процессов

Глава 4
Планирование выполнения процессов
В предыдущей главе были рассмотрены процессы — абстракция операционной системы, связанная с активным программным кодом. В этой главе представлен планировщик процессов — код, который позволяет процессам

Планирование выполнения процессов

Планирование выполнения процессов
Как и оперативная память, процессор является разделяемым ресурсом, который должен быть справедливо распределен между конкурирующими процессами. Планировщик процессов как раз и является той подсистемой ядра, которая обеспечивает

8.1 ПЛАНИРОВАНИЕ ВЫПОЛНЕНИЯ ПРОЦЕССОВ

8.1 ПЛАНИРОВАНИЕ ВЫПОЛНЕНИЯ ПРОЦЕССОВ
Планировщик процессов в системе UNIX принадлежит к общему классу планировщиков, работающих по принципу «карусели с многоуровневой обратной связью». В соответствии с этим принципом ядро предоставляет процессу ресурсы ЦП на квант

Приоритеты прерываний и процессов первого плана

Приоритеты прерываний и процессов первого плана
Существует возможность указания системе приоритета для конкретного прерывания. В зависимости от использования прерывания повышение его приоритета может повысить скорость работы компьютера. Можно также указать

8.5. Отмена выполнения потоков

8.5. Отмена выполнения потоков
Обсуждая листинг 8.4, мы обратили внимание на наличие проблемы, возникающей при отмене выполнения потока, заблокированного вызовом pthread_cond_wait. Выполнение потока может быть отменено в том случае, если какой-нибудь другой поток вызовет функцию

Взаимосвязь процессов, доменов приложений, контекстов и потоков

Взаимосвязь процессов, доменов приложений, контекстов и потоков
В предыдущей главе обсуждалось понятие потока, который был определен, как путь исполнения в рамках выполняемого приложения. И хотя многие приложения .NET имеют только один поток и, тем не менее, оказываются

Приоритеты

Приоритеты
     Операция ! имеет очень высокий приоритет, он выше, чем у умножения, такой же, как у операций увеличения, и только круглые скобки имеют более высокий приоритет. Приоритет операции &amp;&amp; больше чем операции ||, а обе они имеют более низкий приоритет, чем

2.2.1.3 Планирование потоков

2.2.1.3 Планирование потоков
Сервер осведомлен о степени значимости различных потоков и в соответствии с этим назначает для них приоритеты. Например, потоки ввода-вывода получают приоритеты следующим образом: 1. ввод-вывод логической журнализации — наивысший приоритет;2.

3.2.3. Планирование процессов

3.2.3. Планирование процессов
Операционная система Linux планирует работу родительских и дочерних процессов независимо друг от друга. Нет гарантии, что один процесс будет запущен раньше другого. и неизвестно, как долго один процесс будет выполняться, прежде чем Linux прервет

4.6. Сравнение процессов и потоков

4.6. Сравнение процессов и потоков
В некоторых программах, связанных с параллельным выполнением операций, сделать выбор в пользу процессов или потоков может оказаться достаточно сложно. Приведем рад правил, которые помогут читателям выбрать наилучшую модель для своих

Понравилась статья? Поделить с друзьями:
  • В настоящее время ножницы не работают на данном компьютере windows 10
  • В ос windows файловая система иерархическая да или нет
  • В моем компьютере не отображается второй жесткий диск windows 7
  • В ос windows удален ярлык файла notepad exe выберите верное утверждение
  • В микшере громкости нет микрофона windows 10