Цель работ
Изучение возможностей поддержки многозадачного и многопоточного режимов в среде Windows 7.
Получение навыков разработки многозадачных и многопоточных приложений.
Общие сведения
Современные процессоры – это весьма быстродействующие устройства, способные выполнять многие миллионы операций в секунду, и именно это их свойство сделало возможным появление широко распространенных многозадачных ОС, обеспечивают запускать одновременно несколько программ, которые (с точки зрения пользователя) будут выполняться одновременно. На самом же деле в случае работы ОС на компьютере с одним процессором речь может идти лишь о псевдопараллельном выполнении приложений, при котором в каждый момент времени выполняется лишь одна программа, однако, за весьма короткое время процессор успевает последовательно понемногу поработать со всеми программами. При этом всю черновую работу, связанную с распараллеливанием выполнения приложений, берет на себя ОС. В зависимости от объема и «интеллектуальности» этой работы, принято различать несколько видов многозадачности – кооперативную и вытесняющую.
· кооперативная многозадачность (NetWare, Windows 3.x);
· вытесняющая многозадачность (Windows NT, OS/2, UNIX).
Основным различием между вытесняющим и кооперативным вариантами многозадачности является степень централизации механизма планирования процессов. В первом случае механизм планирования процессов целиком сосредоточен в операционной системе, а во втором - распределен между системой и прикладными программами. При кооперативной многозадачности активный процесс выполняется до тех пор, пока он сам, по собственной инициативе, не отдаст управление операционной системе для того, чтобы та выбрала из очереди другой готовый к выполнению процесс. При вытесняющей многозадачности решение о переключении процессора с одного процесса на другой принимается операционной системой, а не самим активным процессом. При этом приложение владеет всеми ресурсами центрального процессора только в течение заранее определенного времени – кванта. По истечении кванта ОС обязательно переключит процессор на выполнение другой задачи.
|
Среда C++ Builder дает возможность создавать приложения для ОС Windows NT/98/Me/2000/XP/7, поддерживающих вытесняющую многозадачность. Это означает, что приложения работают как бы одновременно. Время делится на короткие кванты, по истечению которых ОС переключает его с одной задачи на другую (задачи вытесняют друг друга). Если кванты времени достаточно малы, у пользователя складывается впечатление, что задачи решаются одновременно.
Многозадачность дает следующие преимущества:
· уменьшаются простои процессора и, как следствие, загрузка вычислительных ресурсов компьютера становится более равномерной.
· пользователь быстрее получает результат от менее трудоемких задач.
· зацикливание одной задачи не приводит к блокированию других.
Современные ОС поддерживают двухуровневую схему многозадачности и обеспечивают параллельное выполнение не только целых программ (процессов), но даже подпрограмм внутри одной и той же программы (потоков в рамках процесса). Нижнему уровню многозадачности соответствует название «внутренняя многозадачность» или «многопоточность».
|
Задания, процессы, потоки и волокна. Ядро многозадачных ОС не знает, что такое «программа» или «приложение», вместо них оно использует такие базовые объекты, как процессы и потоки.
Эти два понятия очень важны. Процессом (process) называется экземпляр вашей программы, загруженной в память. Этот экземпляр может создавать потоки (thread), которые представляют собой последовательность инструкций на выполнение. Важно понимать, что выполняются не процессы, а именно потоки. Причем любой процесс имеет хотя бы один поток. Этот поток называется главным (основным) потоком приложения.
ОС Windows существуют свои достаточно специфические объекты – волокна и задания, хотя используются они гораздо реже.
Задания – требования пользователя на выполнение некоторого объёма вычислительных работ. Каждое задание реализуется как определенная совокупность программ, т.е. задач. Задание – отклик системы на запрос пользователя. При управлении ресурсами (заданиями), ОС осуществляет предварительное планирование потока заданий, статическое распределение ресурсов между одновременно выполняемыми заданиями. К этим ресурсам относятся:
· память (оперативная, внешняя, дисковая);
· устройства монопольного использования.
Такие ресурсы закрепляются за заданием с момента его инициализации до момента его завершения. Такое управление называется мониторингом, а осуществляющие его выполнение – мониторами. Управление динамическими ресурсами динамически распределяет ресурсы между задачами решаемыми одновременно. Динамическое управление выполняет супервизор. Управление данными обеспечивает все операции вв/выв, организацию необходимых информационных структур с таблиц, управление файловой системой, управление прямым доступом к памяти, обработка ошибок вв/выв. Управления восстановлением обеспечивает регистрацию машинных сбоев и отказов и восстановление работоспособности системы.
|
Основные аппаратные ресурсы, подлежащие управлению
· Время работы ЦП
· Адресное пространство основной памяти
· Оборудование вв/выв
· Файлы во внешней памяти
Волокно – облегченный поток, полностью управляемый в пространстве пользователя. Волокна подобны потокам, но планируются в пространстве пользователя, создавшей их программой. У каждого потока может быть несколько волокон, с той разницей, что когда волокно блокируется, оно помещается в очередь блокированных волокон. После чего для работы выбирается другие волокна в составе этого же потока. При этом ОС не знает ничего о смене волокон, так как все тот же поток выполняет работу.
Планирование потоков. Так как практически всегда потоков гораздо больше, чем физических процессоров для их выполнения, то потоки на самом деле выполняются не одновременно, а по очереди. (Заметьте, что распределение процессорного времени происходит именно между потоками, так как, процессы не выполняются.) Но переключение между ними происходит так часто, что кажется будто они выполняются параллельно.
В зависимости от ситуации потоки могут находиться в трех состояниях. Во-первых, поток может выполняться, когда ему выделено процессорное время, т.е. он может находиться в состоянии активности. Во-вторых, он может быть неактивным и ожидать выделения процессора, т.е. быть в состоянии готовности. И есть еще третье, тоже очень важное состояние - состояние блокировки. Когда поток заблокирован, ему вообще не выделяется время. Обычно блокировка ставится на время ожидания какого-либо события. При возникновении этого события поток автоматически переводится из состояния блокировки в состояние готовности. Например, если один поток выполняет вычисления, а другой должен ждать результатов, чтобы сохранить их на диск. Второй мог бы использовать цикл типа "while(!isCalcFinished) continue;", но легко убедиться на практике, что во время выполнения этого цикла процессор занят на 100% (это называется активным ожиданием). Таких вот циклов следует по возможности избегать, в чем нам оказывает неоценимую помощь механизм блокировки. Второй поток может заблокировать себя до тех пор, пока первый не установит событие, сигнализирующее о том, что чтение окончено.
В системе выделяются два вида потоков - интерактивные, крутящие свой цикл обработки сообщений (такие, как главный поток приложения), и рабочие, представляющие собой простую функцию. Во втором случае поток завершается по мере завершения выполнения этой функции.
Заслуживающим внимания моментом является также способ организации очередности потоков. Можно было бы, конечно, обрабатывать все потоки по очереди, но такой способ далеко не самый эффективный. Гораздо разумнее оказалось ранжировать все потоки по приоритетам. Приоритет потока обозначается числом от 0 до 31, и определяется исходя из приоритета процесса, породившего поток, и относительного приоритета самого потока. Таким образом, достигается наибольшая гибкость, и каждый поток в идеале получает столько времени, сколько ему необходимо. Приоритет можно изменить с помощью Диспетчера задач, окно которого (рисунок 1) появляется при нажатии клавиш Ctrl + Alt + Del. Перейдя в нем на вкладку «Процессы», можно наблюдать процессы, которые выполняются в системе в настоящий момент.
Для настройки этой вкладки, необходимо открыть меню «Вид», и запустить команду «Выбрать столбцы» (рисунок 2).
Рисунок 1 Диспетчер задач
Рисунок 2 Настройка вкладки
Далее нужно галочкой выбрать столбцы, которые необходимо отображать. Например, необходимо знать объем виртуальной памяти, выделяемый под каждый процесс, его базовый приоритет, а также число потоков данного процесса (рисунок 3).
Для изменения значения приоритета процесса, необходимо щелкнуть правой кнопкой мыши на нужном процессе, выбрать команду «Приоритет», и выбрать его относительное значение (рисунок 4).
Рисунок 3 Выбор столбцов страницы процессов
Рисунок 4 Выбор приоритета процесса
Приостановка, возобновление и полная остановка потока
Выполнение потока можно временно приостановить извне, а затем продолжить с помощью методов Thread::Suspend и Thread::Resume. Их вызовы могут быть вложенными.Прежде чем процесс продолжит работу, нужно вызвать Thread::Resume столько раз, сколько вызывался Thread::Suspend. Для проверки состояния потока используется свойство Suspended.
Так же поток можно и остановить полностью, используя метод Terminate. Он устанавливает свойство Terminate в значение true, сигнализируя о том, что поток должен завершиться. Метод Execute периодически проверяет Terminate, если его значение верно, то работа потока прекращается. Завершение метода Execute, прекращает работу потока и генерирует событие OnTerminate в главном потоке приложения. Событие OnTerminate позволяет приложению отреагировать на завершение своего потока и обычно обрабатывается формой. После завершения, объект потока автоматически разрушается.
Вывод
В ходе выполнения данной лабораторной работы я изучил возможности поддержки многозадачного и многопоточного режимов в среде Windows. Получил навыки разработки многозадачных и многопоточных приложений. Также благодаря выполнению индивидуального задания ознакомился с процедурами приостановки, возобновления и полной остановки потоков.