<Программирование для Windows NT© Александр Фролов, Григорий ФроловТом 26, часть 1, М.: Диалог-МИФИ, 1996, 272 стр. Рецензия PC WEEK Процессы и задачи в Microsoft Windows NTВ операционной системе Microsoft Windows NT существуют два понятия, имеющие отношение к мультизадачности. Это процессы и задачи. Процесс (process) создается, когда программа загружается в память для выполнения. Вы создаете процессы запуская, например, консольные прогрммы или графические приложения при помощи Program Manager. Как мы уже говорили, процессу выделяется в монопольное владение 2 Гбайта изолированного адресного пространства, в которое другие процессы не имеют никакого доступа. Сразу после запуска процесса создается одна задача (thread), или, как ее еще называют в отечественной литературе, поток XE "поток" . Задача - это просто фрагмент кода приложения, который может выполняться автономно и независимо от других задач в рамках одного процесса. Например, функция WinMain в приведенных нами ранее примерах приложений может рассматриваться как задача, которая запускается сразу после запуска процесса. При необходимости эта задача может запускать другие задачи, реализуя таким образом мультизадачность в рамках процесса. Все задачи имеют доступ к памяти, выделенной запустившему их процессу. Из сказанного выше следует, что с одной стороны, в операционной системе Microsoft Windows NT могут работать одновременно несколько процессов, с другой - в рамках каждого процесса могут параллельно работать несколько задач. Пользователь может запустить процесс, загрузив ту или иную программу в память для выполнения, но он не может запустить задачу, так как эта операция выполняется только процессами. Распределение времени между задачамиВажно заметить, что кванты времени для работы выделяются не процессам, а запущенным ими задачам (рис. 2.1). При этом если в системе установлен только один процессор, то задачи выполняются по очереди, создавая иллюзию параллельного выполнения. Рис. 2.1. Квантование времени выполняется для задач Если же в компьютере установлено несколько процессоров, то операционная система выделяет процессоры для выполнения задач и тогда в действительности несколько задач могут работать параллельно. Обычно для совместимости приложения составляются таким образом, чтобы они “не знали” о количестве процессоров в системе. Для оптимальной работы системы необходимо правильно установить закон, по которому кванты времени выделяются задачам. В операционной системе Microsoft Windows NT используется приоритетное планирование задач, когда и процессы, и задачи имеют свои уровни приоритета. При необходимости операционная система может автоматически в небольших пределах изменять приоритеты, повышая, например, приоритет задач, активно работающих с периферийными устройствами компьютера. Операционная система устанавливает уровень приоритета задач XE "уровень приоритета задач" в диапазоне от 1 до 31, причем значение 31 соответствует максимальному приоритету. В процессе планирования кванты времени выделяются задачам с максимальным приоритетом. Менее приоритетные задачи получают управление только в том случае, если более приоритетные задачи переходят в состояние ожидания. Так как рано или поздно это обязательно происходит, то даже задачи с приоритетом, равным 1, имеют большие шансы получить кванты времени. С другой стороны, если во время работы менее приоритеных задач запускается задача с более высоким приоритетом, все низкоприоритетные задачи приостанавливаются, а кванты времени выделяются более приоритетной задаче. На первый взгляд может показаться странным, что приложения не могут устанавливать конкретное значение приоритета задач из указанного интервала значений. Вместо этого используется двухступенчатая система установки приоритетов для процессов и задач. Классы приоритета процессов XE "классы приоритета процессов"При запуске процесса с помощью функции CreateProcess XE "CreateProcess" (которая будет рассмотрена позже), ему можно назначить один из четырех классов приоритета:
Когда приоритет процесса не указывается, то по умолчанию он получает приоритет класса NORMAL_PRIORITY_CLASS XE "NORMAL_PRIORITY_CLASS" . Если это приложение работает в фоновом режиме, операционная система снижает его уровень приоритета до 7, если же окно приложения выдвигается на передний план - увеличивает до 9. Таким образом уровень приоритета приложения, с которым в данный момент работает пользователь, автоматически увеличивается. Класс IDLE_PRIORITY_CLASS XE "IDLE_PRIORITY_CLASS" используется для приложений, которые не должны тормозить работу других приложений. Это могут быть приложения, предназначенные для выполнения какой-либо фоновой работы, отображения постоянно меняющейся информации или приложения, выполняющий большой объем вычислений, сильно загружающих процессор. Например, если ваше приложение выполняет многочасовой расчет, имеет смысл назначить ему класс приоритета IDLE_PRIORITY_CLASS. При этом во время расчета пользователь сможет выполнять и другую работу, например, редактирование текста. В тех случаях, когда приложение должно немедленно отзываться на действия пользователя, ему, возможно, следует назначить класс приоритета HIGH_PRIORITY_CLASS XE "HIGH_PRIORITY_CLASS" . Этот класс приоритета имеет, например, приложение Task Manager, с помощью которого пользователь может переключаться между запущенными приложениями а также завершать приложения. Не следует увлекаться созданием высокоприоритетных приложений, так как если в системе их будет запущенно много, то работа схемы, обеспечивающей оптимальный баланс производительности процессов, будет нарушена. В результате вы не получите желаемого эффекта. Что же касается класса приоритета REALTIME_PRIORITY_CLASS XE "REALTIME_PRIORITY_CLASS" , то он должен использоваться только системными процессами или драйверами. В противном случае будет блокирована работа клавиатуры и мыши, так как они обслуживаются с меньшим уровнем приоритета, чем приоритет классса REALTIME_PRIORITY_CLASS. Относительный приоритет задач XE "относительный приоритет задач"Как мы уже говорили, в рамках одного процесса может быть запущено несколько задач. Точно также как невозможно задать явным образом уровень приоритета процессов (лежащий в диапазоне значений от 1 до 31), невозможно задать и уровень приоритета задач, запущенных процессом. Вместо этого процесс при необходимости устанавливает функцией SetThreadPriority XE "SetThreadPriority" относительный приоритет задач, который может быть несколько ниже или выше приоритета процесса. Указанной выше функции можно передать одно из следующих значений, определяющих новый приоритет задачи относительно приоритета процесса:
Если процесс имеет класс приоритета, равный значению REALTIME_PRIORITY_CLASS XE "REALTIME_PRIORITY_CLASS" , использование относительного приоритета THREAD_PRIORITY_TIME_CRITICAL XE "THREAD_PRIORITY_TIME_CRITICAL" приведет к тому, что уровень приоритета задачи будет равен 31. Если же это значение относительного приоритета укажет процесс более низкого класса приоритета, уровень приоритета задачи установится равным 15. Для процесса с классом приоритета REALTIME_PRIORITY_CLASS XE "REALTIME_PRIORITY_CLASS" использование относительного приоритета THREAD_PRIORITY_IDLE XE "THREAD_PRIORITY_IDLE" приведет к тому, что будет установлен уровень приоритета задачи, равный 16. Если же значение THREAD_PRIORITY_IDLE будет использовано менее приоритетным процессом, уровень приоритета задачи будет равен 1. Операционная система может автоматически изменять приоритет задач, повышая его, когда задача начинает взаимодействовать с пользователем, а затем постепенно уменьшая. Приоритет задач, находящихся в состоянии ожидания, также уменьшается. Процесс может запустить задачу, а потом увеличить ее приоритет. В этом случае главная задача процесса, запустившая более приоритетную задачу, будет временно приостановлена. Если же процесс запустит задачу и уменьшит ее приоритет таким образом, что он станет меньше приоритета главной задачи процесса, будет приостановлена запущенная задача. В составе Resource Kit for Windows NT XE "Resource Kit for Windows NT" и в составе SDK поставляется приложение Process Viewer XE "приложение Process Viewer" (рис. 2.2), пользуясь которым можно просмотреть и в некоторых случаях изменить приоритеты процессов и задач, а также получить другую информацию о запущенных задачах (использованное процессорное время с момента запуска, процент работы системного и пользовательского кода, использование виртуальной памяти и так далее). Рис. 2.2. Приложение Process Viewer С помощью этого приложения вы также можете завершить работу процесса, если возникнет такая необходимость. Проблемы синхронизации задач и процессовСоздавая мультизадачное приложение, необходимо тщательно планировать взаимодействие задач, избегая конфликтных ситуаций, когда различные задачи пытаются одновременно использовать один и тот же ресурс. Например, одна задача может выполнять запись в ячейку памяти нового значения, а вторая - чтение из нее. Результат чтения при этом будет зависеть от момента, когда произойдет чтение - до записи нового значения или после. Возможно возникновение взаимных блокировок задач, когда задачи будут бесконечно ждать друг друга. Операционная система организует для процессов и задач последовательный доступ к таким ресурсам, как принтер или последовательный асинхронный порт, однако если несколько задач вашего приложения рисуют что-либо в одном окне, вы должны сами позаботиться об организации последовательного доступа к таким ресурсам, как контекст отображения, кисти, шрифты и так далее. Специально для организации взаимодействия задач в операционной системе Microsoft Windows NT предусмотрены так называемые объекты синхронизации XE "объекты синхронизации" . Это средства организации последовательного использования ресуросов (mutex), семафоры (semaphore) и события (event). Мы рассмотрим перечисленные средства позже в этой главе. Поиск ошибок, возникающих в результате неправильно организованной синхронизации задач, может отнять много времени, поэтому прежде чем принять решение об использовании мультизадачности в вашем приложении, следует хорошо подумать, нужно ли это и оценить полученные в результате преимущества (если они вообще будут). Передача данных между процессами и задачамиТак как процессы выполняются в изолированных адресных пространствах, возникают некоторые трудности при необходимости организовать обмен данными между процессами. Вы не можете просто предать из одного процесса другому указатели на глобальные области памяти или идентфикаторы каких-либо ресурсов (например, идентификатор кисти, растрового изображения и так далее), так как в контексте другого процесса эти указатели и идентификаторы не имеют смысла. Что же делать? Для передачи данных между процессами XE "передача данных между процессами" вы должны использовать такие средства, как файлы, отображаемые в память, средства динамической передачи данных DDE, трубы и другие специальные средства, которые мы рассмотрим позже. При этом дополнительно необходимо использовать средства синхронизации процессов. Что же касается задач, запущенных в рамках одного процесса, то здесь ситуация несколько легче. Так как все задачи работают в едином адресном пространстве, то они могут обмениваться данными, например, через глобальные переменные. Разумеется, и в этом случае без средств синхронизации не обойтись. |