ActiveThread.h

См. документацию.
00001 /*
00002  * CntmLib - Подсчет ссылок, потоки, синхронизация, асинхронные процедуры, события
00003  * Copyright (c) 2005, Овсеевич Роман, CntmLib@mail.ru
00004  * _______________________________________________________________________________
00005  * Разрешено свободное использование, копирование, распространение, изменение
00006  * (изменение сведений об авторских правах запрещено). Запрещена продажа и 
00007  * включение всей библиотеки или ее частей в другие библиотеки. В сведениях об
00008  * авторских правах на программу (или сведениях о программе, об авторах, 
00009  * использованных средствах разработки и т.д.) должна быть указана информация
00010  * о библиотеке CntmLib, ее авторе и, возможно, сайте или email'е.
00011  * Библиотека поставляется "как есть", без каких-либо гарантий со стороны автора.
00012  */ 
00013 
00014 #ifndef CNTM_ACTIVETHREAD_H
00015 #define CNTM_ACTIVETHREAD_H
00016 #include <Cntm/SystemUtils/SysThread.h>
00017 #include <Cntm/Concurrency/ExecutionUnit.h>
00018 #include <Cntm/ActiveObjects/Internal/ActiveThreadFunctor.h>
00019 #include <Cntm/ActiveObjects/ActiveThreadTerminatingSignal.h>
00020 
00021 namespace Cntm
00022 {
00023         
00024         class ActiveObject;
00025         
00026         /**
00027          * Класс потока активного объекта. Предоставляет средства для запуска потока активного объекта.
00028          * 
00029          * Поток активного объекта является единицей выполнения. Наследует класс Cntm::ExecutionUnit, который предоставляет средства для останова единиц выполнения и потоков активных объектов в частности.
00030          * 
00031          * Запуск потока производится методом Start()(). Методу Start передается активный объект и указатель на его метод. Метод Start() возвращает специальный объект-фанктор, имеющий operator(), принимающий аргументы для указанного метода объекта, запускающего указанный метод в другом потоке. При вызове указанного метода ему будут переданы аргументы,  заданные в методе Start()(). Т.о. вызов метода Start()() выглядит так: Start(активный объект, метод активного объекта)(список аргументов метода активного объекта). При указании аргументов производится проверка типов указанных значений и типов аргументов указанного метода. Типы аргументов должны иметь конструктор копирования, т.к. копии аргументов хранятся на всем протяжении выполнения потока (иначе их невозможно передать в другой поток). Пример:
00032          * class Class1: public ActiveRefBase
00033          * {
00034          * void Thread1(int a, string s) { ... } // Метод, который будет вызван в другом потоке.
00035          * 
00036          * Class1() { ActiveThread::Start(this, &Class1::Thread1)(45, "Text"); } // Вызов метода в новом потоке и передача ему аргументов - числа и строки.
00037          * };
00038          * 
00039          * Взаимодействие с созданным потоком осуществляется через хэндл потока активного объекта (класс Cntm::ActiveThreadHandle). Через хэндл можно сообщить потоку об останове. Поток может узнать об останове через методы Terminated() и CheckTerminating(), унаследованные им от класса Cntm::ExecutionUnit().
00040          * 
00041          * Данный класс обеспечивает многопоточность.
00042          * @author Овсеевич Р.
00043          * \ingroup ActiveObjects
00044          */
00045         class ActiveThread: public ExecutionUnit
00046         {
00047         public:
00048                 
00049                 /**
00050                  * Приоритет потока.
00051                  */
00052                 enum ThreadPriority
00053                 {
00054                         /**
00055                          * Обычный приоритет.
00056                          */
00057                         tpNormal = Cntm::SpecUtils::SysThread::prNormal,
00058                         
00059                         /**
00060                          * Пониженный приоритет.
00061                          */
00062                         tpLow = Cntm::SpecUtils::SysThread::prLow,
00063 
00064                         /**
00065                          * Повышенный приоритет.
00066                          */
00067                         tpHigh = Cntm::SpecUtils::SysThread::prHigh,
00068 
00069                         /**
00070                          * Наивысший приоритет. Может устанавливаться только root'ом.
00071                          */
00072                         tpTimeCritical = Cntm::SpecUtils::SysThread::prTimeCritical
00073                 };
00074 
00075 
00076                 /**
00077                  * Запустить поток активного объекта. Активный объект задается обычным указателем на объект. Если тип объекта не является производным от Cntm::ActiveObject, то будет выдана ошибка компиляции.
00078                  * 
00079                  * После вызова метода Start() в скобках указываются аргументы, которые следует передать запускаемому в новом потоке методу. Если аргументов нет, ставятся круглые скобки. Если после вызова метода Start() не будет второй пары скобок, то поток запущен не будет. Пример:
00080                  * ActiveThread::Start(this, &Class1::Thread1)(45, "Text");
00081                  * ActiveThread::Start(this, &Class1::Thread2)();
00082                  * Метод Start(...) олицетворяет идентификатор функции, а вторая пара скобок - его вызов, поэтому когда говорится о методе Start()() и подобных ему, то указывается две пары скобок.
00083                  * 
00084                  * Метод Start()() возвращает хэндл созданного потока (см. класс Cntm::ActiveThreadHandle).
00085                  * 
00086                  * Исключения:
00087                  * NullArgException - если указатель на активный объект равен NULL, т.е. не задан объект-владелец потока.
00088                  * SystemException - системная ошибка при создании нового потока.
00089                  * @param Object - обычный указатель на активный объект. Не должен равняться NULL.
00090                  * @param Method - указатель на метод активного объекта, который будет вызван в новом потоке.
00091                  * @param Priority - приоритет создаваемого потока. 
00092                  */
00093                 template < typename MethodSignatureT >
00094                 static SpecUtils::ActiveThreadFunctor < typename SignatureInfo < MethodSignatureT > ::FuncSign > Start(typename SignatureInfo < MethodSignatureT > ::ClassType* Object, MethodSignatureT Method, ThreadPriority Priority = tpNormal)
00095                 {
00096                         // Проверка на приводимость к ActiveObject*.
00097                         CheckCastToActiveObject(Object);
00098                         
00099                         // Object пропускаем через RefPtr<ActiveObject> для того, чтобы убедиться, что он не в удаляемом состоянии.
00100                         return SpecUtils::ActiveThreadFunctor<typename SignatureInfo<MethodSignatureT>::FuncSign>
00101                                 ((SpecUtils::SysThread::Priority)Priority, RefPtr<ActiveObject>(Object).Pointer(), GenericMethodNoRefPtr<typename SignatureInfo<MethodSignatureT>::FuncSign>(Object, Method));
00102                 }
00103                 
00104                 /**
00105                  * Запустить поток активного объекта. Активный объект задается ссылочным указателем на объект. Если тип объекта не является производным от Cntm::ActiveObject, то будет выдана ошибка компиляции.
00106                  * 
00107                  * После вызова метода Start() в скобках указываются аргументы, которые следует передать запускаемому в новом потоке методу. Если аргументов нет, ставятся круглые скобки. Если после вызова метода Start() не будет второй пары скобок, то поток запущен не будет. Пример:
00108                  * ActiveThread::Start(p1, &Class1::Thread1)(45, "Text");
00109                  * ActiveThread::Start(p1, &Class1::Thread2)();
00110                  * Метод Start(...) олицетворяет идентификатор функции, а вторая пара скобок - его вызов, поэтому когда говорится о методе Start()() и подобных ему, то указывается две пары скобок.
00111                  * 
00112                  * Метод Start()() возвращает хэндл созданного потока (см. класс Cntm::ActiveThreadHandle).
00113                  * 
00114                  * Исключения:
00115                  * NullArgException - если ссылочный указатель на активный объект равен NULL, т.е. не задан объект-владелец потока.
00116                  * SystemException - системная ошибка при создании нового потока.
00117                  * @param Object - ссылочный указатель на активный объект. Не должен равняться NULL.
00118                  * @param Method - указатель на метод активного объекта, который будет вызван в новом потоке.
00119                  * @param Priority - приоритет создаваемого потока. 
00120                  */
00121                 template < typename MethodSignatureT >
00122                 static SpecUtils::ActiveThreadFunctor < typename SignatureInfo < MethodSignatureT > ::FuncSign > Start(
00123                         const RefPtr < typename SignatureInfo < MethodSignatureT > ::ClassType > & Object, 
00124                         MethodSignatureT Method, 
00125                         ThreadPriority Priority = tpNormal)
00126                 {
00127                         // Проверка на приводимость к ActiveObject*.
00128                         CheckCastToActiveObject(Object.Pointer());
00129                         
00130                         return SpecUtils::ActiveThreadFunctor<typename SignatureInfo<MethodSignatureT>::FuncSign>
00131                                 ((SpecUtils::SysThread::Priority)Priority, Object.Pointer(), GenericMethodNoRefPtr<typename SignatureInfo<MethodSignatureT>::FuncSign>(Object, Method));
00132                 }       
00133         
00134         private:
00135         
00136                 /**
00137                  * Если на данном методе произошла ошибка компиляции, то указанный объект не является активным объектом. 
00138                  */
00139                 static void CheckCastToActiveObject(const ActiveObject* Ptr) {}
00140         };
00141 
00142 }
00143 
00144 #endif //CNTM_ACTIVETHREAD_H

SourceForge.net Logo
© Овсеевич Р.В. Документация по CntmLib 1.1.4 от 28 May 2008. Создано системой  doxygen 1.5.3