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
© Овсеевич Р.В. Документация по CntmLib 1.1.4 от 28 May 2008. Создано системой 1.5.3 |