Программирование >>  Разработка устойчивых систем 

1 ... 168 169 170 [ 171 ] 172 173 174 ... 196


таксис. Хотя многопоточность по-прежнему остается достаточно сложной темой, программисты Java начинают осваивать и применять ее на относительно ранней стадии.

Комитет по стандартизации С++ рассматривает вопрос о включении поддержки многопоточности в следующую версию стандарта С++, но на момент написания книги остается неясным, как все это будет выглядеть. В качестве основы при подготовке этой главы была выбрана библиотека ZThreads, причем помощь авторам оказывал разработчик библиотеки, Эрик Крэхен (Eric Crahen) из IBM. Библиотека ZThreads хорошо спроектирована и свободно распространяется с открытыми текстами по адресу http: zthread.sourceforge.net.

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

Установка библиотеки ZThreads

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

Библиотека ZThreads распространяется на уровне исходных текстов. После ее загрузки (версии 2.3 и выше) с сайта необходимо откомпилировать библиотеку и подготовить проект к использованию библиотеки.

В большинстве разновидностей Unix (Linux, SunOS, Cygwin и т. д.) компиляцию ZThreads рекомендуется производить при помощи конфигурационного сценария. После распаковки файлов утилитой tar выполните в основном каталоге архива ZThreads команду

./configure && make install

Команда компилирует и устанавливает копию библиотеки в каталог /usr/local. При использовании этого сценария можно задать множество параметров, в том числе определяющих расположение файлов. Чтобы получить дополнительную информацию, выполните команду

./configure -help

Код ZThreads структурирован таким образом, чтобы упростить компиляцию для других платформ и компиляторов (таких, как Borland, Microsoft и Metrowerks). Для этого следует создать новый проект и включить все схх-файлы из каталога src архива ZThreads в список компилируемых файлов. Также не забудьте включить каталог include архива в список путей к заголовочным файлам вашего проекта. Подробности зависят от конкретного компилятора, поэтому для использования этой возможности вы должны достаточно хорошо разбираться в своем инструментарии.

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

-I/nyrt/include



Определение задач

Каждый программный поток решет некоторую задачу; следовательно, нам понадобятся средства для описания подобных задач. Класс Runnable определяет общий интерфейс для выполнения произвольной задачи. Ниже приведено ядро класса Runnable библиотеки ZThread, находящееся в файле Runnable.h каталога include после установки библиотеки ZThread:

class Runnable { public:

virtual void runO = 0:

virtual void -RunnableO {}

Определение Runnable в виде абстрактного базового класса позволяет легко объединять его с другими классами.

Чтобы определить задачу, просто объявите ее класс производным от класса Runnable и переопределите функцию run() так, чтобы она выполняла нужные действия.

Например, следующая задача LiftOff осуществляет обратный отсчет до нуля:

: Cll:LiftOff.h

Демонстрация интерфейса Runnable.

#ifndef LIFTOFF H

#define LIFTOFFJ

#include zthread/Runnable.h

Если вы задействовали сценарий configure, то путь определяется выбранным префиксом (по умолчанию /usr/local/). А при использовании файлов проектов из каталога build он просто соответствует пути к основному каталогу архива ZThreads.

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

-L/nyrb/lib -IZThread

При использовании файлов проектов он принимает вид

-L/nyyb/Debug Zthread.lib

Как и при определении местонахождения заголовочных файлов, если вы задействовали сценарий configure, путь определяется выбранным префиксом (по умолчанию /usr/local/). А в случае готовых файлов проектов он соответствует пути к основному каталогу архива ZThreads.

Если вы используете Linux или Cygwin (www.cygwin.com) в среде Windows, возможно, изменять пути к заголовочным или библиотечным файлам не понадобится; процесс установки часто рещает эту задачу за вас.

Вероятно, в системе Linux вам придется включить следующую строку в .bashrc, чтобы система времени выполнения могла находить общую библиотеку LibZThread-X.X.SO.0 при выполнении программ, приводимых в этой главе (предполагается, что вы использовали стандартный процесс установки, а общая библиотека находится в каталоге /usr/local/lib; в противном случае соответствующим образом измените путь):

export LD LIBRARY PATH=/usг/1 oca1/11b:${LD LIBRARY PATH}



Программные потоки

Чтобы запустить объект Runnable в отдельном программном потоке, создайте объект Thread и передайте его конструктору указатель на Runnable. Тем самым обеспечивается инициализация программного потока и дальнейшее выполнение в нем функции run() класса Runnable под управлением операционной системы. Следующий пример, в котором Thread управляет работой Liftoff, показывает, как организуется запуск задачи в контексте программного потока:

: Cll:BasicThreads.cpp

Простейшее использование класса Thread

{L} ZThread

linclude <iostream>

linclude LiftOff.h

linclude zthread/Thread.h

using namespace ZThread:

linclude <iostreani>

class Liftoff : public ZThread::Runnable {

int countDown:

int id: public:

Liftoff(int count, int ident = 0) :

countDown(count). id(ident) {} -LiftoffО {

std::cout id completed std::endl:

void runO { while(countDown--)

std::cout id : countDown std::endl: std::cout Liftoff! std::endl:

lendif LIFT0FF H /:-

Переменная id идентифицирует разные экземпляры одной задачи. Если программа запускается в единственном экземпляре, передайте значение по умолчанию в параметре ident. Деструктор помогает убедиться в том, что объект задачи был должным образом уничтожен.

В следующем примере функция гип() объекта задачи запускается не в отдельном потоке, а напрямую вызывается в main():

: Cll:NoThread.cpp linclude LiftOff.h

int mainO {

Liftoff launch(lO):

launch. runO: } III:-

Классы, производные от Runnable, должны содержать функцию run(), но эта функция не делает ничего особенного - она не обладает никакими особыми многопоточными свойствами.

Многопоточное выполнение программы обеспечивается классом Thread.



1 ... 168 169 170 [ 171 ] 172 173 174 ... 196

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика