49. Понятие о процессах и потоках в Windows-приложениях. Пример.

Среда Delphi дает возможность создавать приложения для операционной системы Windows. Эта операционная система поддерживает вытесняющую многозадачность, позволяя приложениям работать как бы одновременно. Время работы процессора делится на короткие кванты, по истечении которых операционная система переключает его с одной задачи на другую (задачи вытесняют друг друга). Если кванты времени достаточно малы, у пользователя складывается впечатление, что задачи решаются одновременно. Что же дает многозадачность?

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

Операционная система Windows поддерживает двухуровневую схему многозадачности и обеспечивают параллельное выполнение не только целых программ (процессов), но даже подпрограмм внутри одной и той же программы (потоков в рамках процесса).
¦ Процесс (process) — это выполняемая программа, имеющая собственное виртуальное адресное пространство, код, данные, а также потребляющая ресурсы операционной системы, такие как файлы, окна и т.д. Процессы порождаются запуском новых экземпляров приложений.
¦ Поток (thread) — это подпрограмма, выполняемая параллельно с главной программой (вообще говоря, главная программа тоже считается потоком, но этот поток ассоциирован с целым процессом). Поток может выполнять любую подпрограмму, более того, одна и та же подпрограмма может одновременно выполняться несколькими потоками. Все потоки имеют одно и то же виртуальное адресное пространство, обращаются к одним глобальным переменным и ресурсам своего процесса. Поток — это базовая единица, которой операционная система выделяет время процессора.
Процессы сравнимы по масштабу с программами и позволяют параллельно решать большие задачи. Созданием процессов в основном занимается пользователь, который запускает новые экземпляры приложений. Потоки сравнимы по масштабу с подпрограммами и позволяют параллельно выполнять несколько работ в рамках одного приложения. С помощью потоков можно, например, организовать одновременную проверку синтаксиса одного документа и редактирование другого. В приложении, работающем с базами данных, потоки позволяют выполнять длительные SQL-запросы параллельно с просмотром других данных. Создание, управление и синхронизация потоков полностью лежит на плечах программиста, поэтому эти вопросы мы сейчас и рассмотрим.

ПРЕДСТАВЛЕНИЕ ПОТОКА В DELPHI
В Delphi потоки представляются объектами. Чтобы создать поток, необходимо породить новый класс от класса TThread (объявлен в модуле Classes), перекрыть в нем виртуальный метод Execute и поместить в этот метод программный код потока.
Запуск потока осуществляется путем создания объекта такого класса. В момент создания у объекта автоматически вызывается метод Execute, который начинает выполняться одновременно с участком кода, создавшим поток. После работы метода Execute поток автоматически завершается и объект потока уничтожается.

СИНХРОНИЗАЦИЯ ПОРОЖДЕННОГО ПОТОКА С ГЛАВНЫМ ПОТОКОМ
При программировании метода Execute помните, что вы не можете просто так обратиться к свойствам и методам форм и их компонентов, поскольку эти действия приводят к конфликту между потоками. Например, нельзя изменить свойство Caption формы, потому что в этот момент главная программа может его читать. Проблема состоит в том, что, разделяя время работы процессора, операционная система может прервать поток в любой момент времени и передать управление другому потоку. Одновременный доступ к общим объектам оказывается непредсказуемым и может привести даже к зависанию приложения.
Для корректной работы нужно синхронизировать работу потока с главной программой. Делается это так. В классе потока вы объявляете метод (например, SetFormCaption), который выполняет установку свойства Caption формы:
В программном коде потока (в методе Execute) вы вызываете специальный метод Synchronize и передаете ему ссылку на свой метод: Synchronize(SetFormCaption);
Метод Synchronize дождется подходящего момента времени и выполнит указанный вами метод атомарно по отношению к главному потоку приложения. Такое решение исключает все возможные конфликты.

УПРАВЛЕНИЕ ПРИОРИТЕТОМ ОБСЛУЖИВАНИЯ ПОТОКА
По истечении каждого кванта времени операционная система выполняет планирование потоков, принимая решение о том, какому из них передать управление. Планирование потоков выполняется в соответствии со шкалой приоритетов. Следующий квант времени процессора отдается потоку с наибольшим приоритетом. Если несколько потоков имеют одинаковый приоритет, то управление передается тому, который ожидает своей очереди дольше всех.
Приоритет потока представлен в классе TThread свойством Priority. Приоритет потока можно повышать и понижать по мере необходимости. Возможные значения свойства в порядке повышения приоритета: tpldle, tpLowest, tpLower, tpNormal, tpHigher, tpHighest, tpTimeCritical.

ПРИОСТАНОВКА И ПРОДОЛЖЕНИЕ РАБОТЫ ПОТОКА
Выполнение потока можно временно приостановить извне, а затем продолжить с помощью методов Suspend и Resume. Их вызовы могут быть вложенными. Прежде, чем процесс действительно продолжит работу, необходимо столько раз вызвать метод Resume, сколько раз до этого вызывался метод Suspend. Если необходимо проверить состояние потока (приостановлен или работает), используется свойство Suspended. Это свойство доступно по записи и может использоваться как альтернатива методам Suspend и Resume.

ПРЕКРАЩЕНИЕ РАБОТЫ ПОТОКА
Для прекращения работы потока извне используется метод Terminate. Он устанавливает свойство Terminated в True, сигнализируя о том, что поток должен завершиться. Метод Execute должен периодически проверять свойство Terminated; если оно равно True, необходимо немедленно завершить выполнение метода. Завершение метода Execute прекращает работу потока и генерирует событие OnTerminate в главном потоке приложения. Событие OnTerminate позволяет приложению отреагировать на завершение своего потока и обычно обрабатывается формой. После завершения потока объект потока автоматически разрушается, если его свойство FreeOnTerminate установлено в значение True. Если свойство FreeOnTerminate равно False (устанавливается по умолчанию), разрушение объекта потока возложено на вас.

 

 

 

Конструктор сайтов - uCoz