Главная » C++, C++ Builder » Работа с потоками в CBuilder

0

Когда я произношу слово thread (поток; дословно: нить), о чем вы думаете1 ? О небольших белых кусочках хлопка на вашем деловом костюме? О мотках для вязания с воткнутыми спицами? В компьютерной индустрии, однако, слово thread означает нечто совершенно другое.

Потоки (threads) в компьютерном мире обозначают параллельные процессы, которые  работают внутри вашего приложения. Ваша программа состоит из потоков, хотя вы, наверное, никогда об этом не задумывались. Когда вы отображаете форму на экране, она работает в потоке. Обычно все формы приложения запущены в одном и том же потоке; такое приложение называется однопоточным (single-threaded). Когда вы используете более одного потока в приложении, ваша программа называется многопоточной или мультипоточной (multi-threaded).  Вот так.  Вы  знаете все, что нужно, о потоках. Ну, не совсем. Есть еще парочка вопросов: Что такое на самом деле потоки? Зачем они мне нужны? Как их использовать? Ответы на все эти вопросы вы найдете здесь, в главе, посвященной потокам и их использованию в приложениях CBuilder.

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

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

Зачем нужны потоки? В старые недобрые времена программирования под MS-DOS мы создавали TSR (Terminate and Stay Resident), то есть резидентные программы. TSR — фоновая программа, которая выполняется, пока операционная система занята другими вещами. Резидентные программы были удобны для перехвата нажатий определенных клавиш, фоновой работы с принтером, обновлении времени в часах на экране и т. д. Эти твари были очень ограниченными по возможностям, и их надо было писать в  основном на ассемблере, чтобы они были как можно меньше и быстрее.

Когда наступила эра программирования под Windows, программы стали работать обычным образом. Менеджер процессов в Windows мог сказать программе, чтобы она остановилась, и запустить вторую, но пока от второй программы не приходило  подтверждение  запроса, продолжала выполняться первая. Windows 95 и Windows NT являются «господствующими» операционными системами и могут действительно управлять системой, в частности останавливать работающую программу. Тогда запускаются другие программы на уровне операционной системы. Потоки же являются самостоятельным образованием в том смысле, что вы можете временно приостановить поток и снова его запустить, но окончание его работы является исключительной прерогативой потока. Операционная система, конечно, может убить поток (как обычно называют завершение его работы) в любой момент времени. Ваша же программа, хотя она и породила этот поток, может только приостановить его.

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

Зачем нужны потоки?

Если вы некоторое время работали в Windows, то вы, вероятно, знакомы с фоновыми (background) процессами, которые выполняются во время простоя, когда ваша программа не обрабатывает ввод данных от пользователя и не совершает еще какое-нибудь действие по запросу пользователя. В системе CBuilder имеется встроенная поддержка обработки времени простоя (idle time), но использование потоков является предпочтительным методом для фоновой работы. У потока есть масса преимуществ перед системой обработки времени простоя. Во-первых, вам не нужно беспокоиться о времени, которое занимает какая-нибудь операция. Во-вторых, если вам нужно делать несколько вещей в фоновом режиме, то вам придется каким-то  образом  самому распределять время между этими задачами. Вам придется запускать первую задачу, останавливать ее, запускать вторую и т. д. Потоковая система уже имеет встроенное распределение времени и управление процессами.

Вторая причина, по которой стоит использовать потоки, состоит в том, что потоки не мешают нормальной обработке сообщений в вашем приложении.  Если  вы  писали  циклы  фоновой обработки в стандартном приложении Windows (без использования библиотек классов типа MFC), то вы, наверное, замечали, что ваш алгоритм эквивалентен циклу обработки сообщений. Обычно циклы фоновой обработки выглядят примерно так:

while ( !done )

{

// Происходит какая-нибудь обработка

// Обрабатывать все ожидающие в очереди сообщения,

// иначе вся система остановится while ( GetMessage(&msg) ) DispatchMessage(&msg);

}

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

Источник: Теллес М. – Borland C++ Builder. Библиотека программиста – 1998

По теме:

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