Главная » Delphi » Создание многопоточных приложений

0

Концепция потоков

Поток (thread) — это объект операционной системы, который представляет собой отдельный путь выполнения программы внутри  определенного процесса. Каждое приложение Win32 имеет, по крайней мере,  один  поток, обычно называемый первич ным, или  главным, но  приложения имеют  право  создавать дополнительные потоки, предназначенные для выполнения других задач.

1

 

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

CОВЕТ

Потоки никогда не поддерживались в среде 16-разрядной Windows. Это означает, что ни одна 32-разрядная программа Delphi, написанная с использованием потоков, никогда не будет совместимой с Delphi 1. Данный момент обязательно нужно учитывать при разработ- ке приложений, предназначенных для работы на обеих платформах.

Типы многозадачности

Понятие потока во многом отличается от многозадачности, поддерживаемой в среде

16 разрядной Windows.  Возможно, читателю приходилось слышать, что  Win32 называ ют операционной системой с приоритетной (preemptive), или вытесняющей, многозадачно стью, а Windows 3.1 — средой с кооперативной многозадачностью (cooperative multitasking).

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

В среде  Windows 3.1 ответственность за возвращение управления операционной системе по  завершении выполнения приложения лежит  целиком на  разработчике. Поэтому, когда приложению не удается корректно завершить работу и вернуть управ 1 Обычно в единицах по 100 наносекунд. — Прим. ред.ление  операционной системе, кажется, что операционная система  “зависает” — все хорошо знакомы с такой  печальной ситуацией. Если  вдуматься,  то  это  может  пока заться  даже  забавным —  устойчивость работы всей  системы 16 разрядной Windows полностью зависит от поведения всех ее приложений, которые должны  самостоятель но защитить себя от попадания в бесконечные циклы, замкнутую цепь рекурсии и дру гие неприятные ситуации. А поскольку  все приложения для достижения корректной работы системы должны  работать согласованно, этот  тип многозадачности называет ся кооперативным.

Использование многопоточности в приложениях Delphi

Не  секрет, что  потоки —  серьезное подспорье для программистов Windows.  Вто ричные потоки в приложениях можно  создавать везде,  где требуется выполнение не которых фоновых задач. Типичным примерами таких  действий является вычисление значений отдельных ячеек  электронных таблиц  или  помещение в буфер  документа MS Word при выводе  его на печать. В этом случае задача разработчика — организовать необходимую обработку фоновых процессов, сохранив при  этом  приемлемое время реакции пользовательского интерфейса приложения.

Большая часть компонентов библиотеки VCL построена на предположении, что доступ к ним в каждый конкретный момент времени будет выполняться только  из одного потока. Хотя это замечание особенно справедливо в отношении компонентов библиотеки VCL, используемых для создания пользовательского интерфейса, тем не менее важно понимать, что оно справедливо и для большинства других типов компонентов.

Невизуальные компоненты библиотеки VCL

Существует  всего  несколько областей, в которых подпрограммы библиотеки VCL гарантированно поддерживают многопоточность. Возможно, самым заметным в этом отношении является механизм поддержки свойств поточного ввода/вывода  компо нентов VCL. Особенности его реализации дают полную уверенность, что потоки дан ных в компонентах могут эффективно считываться и записываться сразу несколькими процессами. Помните, что  даже важнейшие базовые классы  в библиотеке VCL (например класс TList) спроектированы без поддержки доступа к ним одновременно из нескольких потоков. В некоторых случаях подпрограммы библиотеки VCL предос тавляют “потокобезопасное” альтернативное решение, к которому можно  обратиться в случае необходимости. В частности, если несколько потоков должны  одновременно манипулировать  некоторым  списком, то  для  его  реализации следует  использовать класс TThreadList, а не обычный класс TList.

Визуальные компоненты библиотеки VCL

Подпрограммы библиотеки VCL требуют, чтобы  все управление пользовательским интерфейсом происходило в контексте основного потока приложения (исключение составляет “потокобезопасный” класс TCanvas, речь  о котором пойдет в настоящей главе далее).  Конечно, существуют решения, позволяющие выполнять обновление пользовательского интерфейса со стороны вторичных потоков (подробнее это будет описано  ниже).  Но  данное  ограничение  заставляет  разработчиков  приложений  ис пользовать потоки более  осторожно. В примерах, приведенных в этой  главе,  демон стрируются некоторые идеальные варианты использования многопоточности в при ложениях Delphi.

Неправильное использование потоков

В любом деле важно  не переборщить. Это утверждение справедливо и в отношении потоков. Несмотря на то что потоки оказывают неоценимую помощь  в решении одних вопросов, они могут принести с собой  целый  букет новых  проблем. Предположим, на пример, что  необходимо создать  интегрированную среду разработки, компилятор ко торой будет работать в своем  собственном потоке, а программист сможет  продолжать работу  с приложением во время  компиляции программы. Здесь  могут возникнуть про блемы  вот какого  плана.  Что  будет, если  внести изменения в файл,  компилируемый в данный момент?  Можно  предложить несколько вариантов решения этой  проблемы. Например, можно  создать  временную копию  файла  в момент его компиляции или сде лать недоступными для редактирования файлы, компиляция которых еще не заверше на. Все дело в том, что потоки не являются панацеей. Решая те или иные  проблемы раз работки, они  неминуемо порождают новые, чреватые  появлением ошибок, которые очень  трудно  устранить при  отладке. Разработка и реализация кода,  обеспечивающего устойчивую  работу потоков, — задача не из легких,  поскольку  в этом случае приходится учитывать гораздо больше факторов, чем при разработке однопоточного приложения.

Источник: Тейксейра, Стив, Пачеко, Ксавье.   Borland Delphi 6. Руководство разработчика. : Пер.  с англ. — М. : Издательский дом “Вильямс”, 2002. —  1120 с. : ил. — Парал. тит. англ.

По теме:

  • Комментарии