PIP 5.5.3
Platform-Independent Primitives
Открытые типы | Открытые члены | Открытые статические члены | Защищенные члены | Полный список членов класса
Класс PIThread

Класс потока Подробнее...

#include <pithread.h>

Граф наследования:PIThread:
Inheritance graph
[см. легенду]

Открытые типы

enum  Priority {
  piLowerst , piLow , piNormal , piHigh ,
  piHighest
}
 Приоритет потока Подробнее...
 

Открытые члены

 PIThread (void *data, ThreadFunc func, bool startNow=false, PISystemTime loop_delay={})
 Создает поток с данными "data", функцией "func" и задержкой цикла "loop_delay".
 
 PIThread (std::function< void()> func, bool startNow=false, PISystemTime loop_delay={})
 Создает поток с функцией "func" и задержкой цикла "loop_delay".
 
 PIThread (bool startNow=false, PISystemTime loop_delay={})
 Создает поток с задержкой цикла "loop_delay".
 
bool start ()
 Запускает поток
 
bool start (PISystemTime loop_delay)
 Запускает поток
 
bool start (ThreadFunc func)
 Запускает поток
 
bool start (ThreadFunc func, PISystemTime loop_delay)
 Запускает поток
 
bool start (std::function< void()> func)
 Запускает поток
 
bool start (std::function< void()> func, PISystemTime loop_delay)
 Запускает поток
 
bool startOnce ()
 Запускает поток без внутреннего цикла Подробнее...
 
bool startOnce (ThreadFunc func)
 Запускает поток без внутреннего цикла Подробнее...
 
bool startOnce (std::function< void()> func)
 Запускает поток без внутреннего цикла
 
bool stopAndWait (PISystemTime timeout={})
 Останавливает поток и ожидает завершения. Возвращает false если таймаут истек.
 
void setData (void *d)
 Устанавливает данные, передаваемые в функцию потока
 
void setSlot (ThreadFunc func)
 Устанавливает функцию потока, вызываемую после каждого run()
 
void setSlot (std::function< void()> func)
 Устанавливает функцию потока, вызываемую после каждого run()
 
void setPriority (PIThread::Priority prior)
 Устанавливает приоритет потока
 
void * data () const
 Возвращает данные, передаваемые в функцию потока
 
PIThread::Priority priority () const
 Возвращает приоритет потока
 
bool isRunning () const
 Возвращает исполняется ли поток
 
bool isStopping () const
 Возвращает останавливается ли поток
 
bool waitForStart (PISystemTime timeout={})
 Ожидает старта потока
 
bool waitForStart (int timeout_msecs) DEPRECATEDM("use waitForStart(PISystemTime)")
 
bool waitForFinish (PISystemTime timeout={})
 Ожидает завершения потока. Возвращает false если таймаут истек.
 
bool waitForFinish (int timeout_msecs) DEPRECATEDM("use waitForFinish(PISystemTime)")
 
void needLockRun (bool need)
 Устанавливает необходимость блокировки внутреннего мьютекса каждый run()
 
PIMutexmutex () const
 Возвращает внутренний мьютекс
 
llong tid () const
 Возвращает ID потока
 
- Открытые члены унаследованные от PIObject
 PIObject (const PIString &name=PIString())
 Создает PIObject с именем "name".
 
PIString name () const
 Возвращает имя объекта
 
virtual const char * className () const
 Возвращает имя класса объекта
 
virtual const char * parentClassName () const
 Возвращает имя родительского класса
 
bool debug () const
 Возвращает включен ли вывод piCoutObj для этого объекта
 
void setName (const PIString &name)
 Устанавливает имя объекта
 
void setDebug (bool debug)
 Включает или отключает вывод piCoutObj для этого объекта
 
PIVariant property (const char *name) const
 Возвращает свойство объекта по имени "name".
 
void setProperty (const char *name, const PIVariant &value)
 Устанавливает у объекта свойство по имени "name" в "value". Если такого свойства нет, оно добавляется
 
bool isPropertyExists (const char *name) const
 Возвращает присутствует ли свойство по имени "name".
 
PIStringList scopeList () const
 Возвращает цепочку наследования объекта (вместе с классом самого объекта)
 
void piDisconnect (const PIString &sig, PIObject *dest, void *ev_h)
 Разрывает все соединения от события "sig" к объекту "dest" и обработчику "ev_h".
 
void piDisconnect (const PIString &sig, PIObject *dest)
 Разрывает все соединения от события "sig" к объекту "dest".
 
void piDisconnect (const PIString &sig)
 Разрывает все соединения от события "sig".
 
bool isPIObject () const
 Возвращает действительный ли это PIObject (проверяет подпись)
 
template<typename T >
bool isTypeOf () const
 Возвращает действительный ли это наследник PIObject типа "T" (проверяет подпись и имя класса)
 
template<typename T >
T * cast () const
 Возвращает преобразование к типу T если это действительный наследник типа "T" (проверяет через isTypeOf()), или "nullptr".
 
void callQueuedEvents ()
 Выполнить все отложенные события от CONNECTU_QUEUED соединений
 
bool maybeCallQueuedEvents ()
 Если было хотя бы одно CONNECTU_QUEUED соединение с исполнителем this, то выполнить события Подробнее...
 
void deleteLater ()
 Пометить объект на удаление Подробнее...
 
void deleted (PIObject *o)
 Вызывается перед удалением объекта Подробнее...
 

Открытые статические члены

static void runOnce (PIObject *object, const char *handler, const PIString &name=PIString())
 Вызывает обработчик "handler" объекта "object" в отдельном потоке Подробнее...
 
static void runOnce (std::function< void()> func, const PIString &name=PIString())
 Вызывает лямбда-выражение "func" в отдельном потоке Подробнее...
 
- Открытые статические члены унаследованные от PIObject
static void piDisconnect (PIObject *src, const PIString &sig, PIObject *dest, void *ev_h)
 Разрывает все соединения от события "sig" объекта "src" к объекту "dest" и обработчику "ev_h".
 
static void piDisconnect (PIObject *src, const PIString &sig, PIObject *dest)
 Разрывает все соединения от события "sig" объекта "src" к объекту "dest".
 
static void piDisconnect (PIObject *src, const PIString &sig)
 Разрывает все соединения от события "sig" объекта "src".
 
static PIObjectfindByName (const PIString &name)
 Returns PIObject* with name "name" or 0, if there is no object found.
 
static bool isPIObject (const PIObject *o)
 Возвращает действительный ли "o" PIObject (проверяет подпись)
 
template<typename T >
static bool isTypeOf (const PIObject *o)
 Возвращает действительный ли "o" наследник PIObject типа "T" (проверяет подпись и имя класса)
 

Защищенные члены

virtual void begin ()
 Метод выполняется один раз при старте потока
 
virtual void run ()
 Метод выполняется каждые "loop_delay" миллисекунд
 
virtual void end ()
 Метод выполняется один раз при остановке потока
 
- Защищенные члены унаследованные от PIObject
PIObjectemitter () const
 Возвращает PIObject* который вызвал это событие. Значение допустимо только из методов обработчиков событий
 
virtual void propertyChanged (const char *name)
 Виртуальная функция, вызывается после изменения любого свойства.
 

Handlers

void stop ()
 Останавливает поток Подробнее...
 
void terminate ()
 Жёстко прерывает поток Подробнее...
 
void lock () const
 Блокирует внутренний мьютекс
 
void unlock () const
 Разблокирует внутренний мьютекс
 

Events

void started ()
 Вызывается при старте потока
 
void stopped ()
 Вызывается при завершении потока
 

Дополнительные унаследованные члены

Подробное описание

Класс потока

Этот класс позволяет выполнять код из параллельного потока.

Краткий обзор

Многопоточность позволяет исполнять код в нескольких потоках одновременно и использовать все ядра современных процессоров. Однако это таит в себе опасности.

Этот класс предоставляет виртуальные методы begin(), run() и end(), которые описывают старт, выполнение и завершение потоковой задачи. Все эти методы исполняются в отдельном потоке. Когда выполняется start(int), PIThread создает отдельный поток средствами ОС и последовательно выполняет begin(), run() и end(). Можно переопределить каждый метод для реализации нужной задачи.

Схема выполнения методов:

virtual begin()
event started()
while (isRunning()) { // while not stop()
virtual run()
ThreadFunc() // Slot or lambda
piMSleep(loop_delay) // if loop_delay > 0
}
event stopped()
virtual end()
bool isRunning() const
Возвращает исполняется ли поток
Definition: pithread.h:183
void started()
Вызывается при старте потока
virtual void begin()
Метод выполняется один раз при старте потока
Definition: pithread.h:276
virtual void run()
Метод выполняется каждые "loop_delay" миллисекунд
Definition: pithread.h:280
void stopped()
Вызывается при завершении потока
virtual void end()
Метод выполняется один раз при остановке потока
Definition: pithread.h:284
void piMSleep(double msecs)
Точно ожидает "msecs" миллисекунд
Definition: pitime.h:42

Если внутренний цикл не нужен, то можно использовать метод startOnce() вместо start(int).

В этом случает схема выполнения следущая:

virtual begin()
event started()
virtual run()
ThreadFunc() // Slot or lambda
event stopped()
virtual end()

В отличии от прямого использования "pthread" или похожих механизмов нет необходимости писать свой цикл внутри поточного метода и ожидать в его теле. PIThread уже рализует такой цикл, необходимо лишь установить значение ожидания в конструкторе или при запуске потока, и переопределить методы begin(), run() и end().

Использование с внутренним циклом

class MyThread: public PIThread {
PIOBJECT_SUBCLASS(MyThread, PIThread)
public:
void begin() override {piCout << "thread begin";}
void run() override {piCout << "thread run" << ++cnt;}
void end() override {piCout << "thread end";}
private:
int cnt = 0;
};
int main(int argc, char * argv[]) {
MyThread mt;
mt.start(100);
piMSleep(500);
mt.stop(true);
return 0;
}
// thread begin
// thread run 1
// thread run 2
// thread run 3
// thread run 4
// thread run 5
// thread end
Класс потока
Definition: pithread.h:72
#define piCout
Макрос для условного (piDebug) вывода в PICout(StdOut)
Definition: picout.h:35

Использование без внутреннего цикла

class MyThread: public PIThread {
PIOBJECT_SUBCLASS(MyThread, PIThread)
public:
void begin() override {piCout << "thread begin";}
void run() override {piCout << "thread run" << ++cnt;}
void end() override {piCout << "thread end";}
private:
int cnt = 0;
};
int main(int argc, char * argv[]) {
MyThread mt;
mt.startOnce();
piMSleep(500);
mt.stop(true);
return 0;
}
// thread begin
// thread run 1
// thread end

Использование без наследования

Возможно использовать PIThread без наследования. Можно передать ему в конструкторе или при запуске указатель на внешний метод "ThreadFunc". В основном цикле потока, если "ThreadFunc" существует, он будет вызываться после run().

ThreadFunc может быть любым статическим методом в формате "void func(void * data)", либо лямбда-выражение в формате [...]( ){...}. "Data" является произвольным указателем, задаваемым в конструкторе или методом setData().

Также можно присоединиться к событию started(), но в этом случае надо будет своими силами реализовать весь цикл, т.к. это событие вызывается один раз после запуска потока.

Использование с внутренним циклом

void myThreadFunc(void * d) {
int * cnt = (int*)d;
piCout << "thread run" << ++(*cnt);
}
int main(int argc, char * argv[]) {
int cnt = 0;
mt.setData(&cnt);
mt.start(myThreadFunc, 100);
piMSleep(500);
mt.stop(true);
return 0;
}
// thread run 1
// thread run 2
// thread run 3
// thread run 4
// thread run 5
bool start()
Запускает поток
Definition: pithread.cpp:599
void setData(void *d)
Устанавливает данные, передаваемые в функцию потока
Definition: pithread.h:157
void stop()
Останавливает поток
Definition: pithread.cpp:661

Использование без внутреннего цикла

void myThreadFunc(void * d) {
int * cnt = (int*)d;
piCout << "thread run" << ++(*cnt);
}
int main(int argc, char * argv[]) {
int cnt = 0;
mt.setData(&cnt);
mt.startOnce(myThreadFunc);
piMSleep(500);
mt.stop(true);
return 0;
}
// thread run 1
bool startOnce()
Запускает поток без внутреннего цикла
Definition: pithread.cpp:637

Использование с лямбда-выражением

int main(int argc, char * argv[]) {
int cnt = 0;
mt.start([&cnt](){
piCout << "thread run" << ++cnt;
}, 100);
piMSleep(500);
mt.stop(true);
return 0;
}
// thread run 1
// thread run 2
// thread run 3
// thread run 4
// thread run 5

Использование с событием

class MyObj: public PIObject {
PIOBJECT(MyObj)
public:
EVENT_HANDLER(void, threadRun) {
piForTimes (5) {
piCout << "threadRun" << ++cnt;
piMSleep(100);
}
};
private:
int cnt = 0;
};
int main(int argc, char * argv[]) {
MyObj mo;
CONNECTU(&mt, started, &mo, threadRun);
mt.startOnce();
mt.stop(true);
return 0;
}
// threadRun 1
// threadRun 2
// threadRun 3
// threadRun 4
// threadRun 5
Этот класс является базовым для использования механизма события -> обработчики.
Definition: piobject.h:41
#define CONNECTU(src, event, dest, handler)
Соединяет событие "event" объекта "src" к обработчику или событию "handler" объекта "dest".
Definition: piobject_macros.h:184
#define EVENT_HANDLER
Аналог EVENT_HANDLER0.
Definition: piobject_macros.h:83
#define PIOBJECT(name)
Необходимо использовать этот макрос после объявления класса для использования событийной системы и ко...
Definition: piobject_macros.h:38
#define piForTimes(c)
Макрос для короткой записи стандартного цикла "for".
Definition: picontainers.h:134

Блокировки

PIThread имеет встроенный мьютекс, который может блокироваться и разблокироваться каждый run() при установленном needLockRun(true). К нему есть доступ через методы lock(), unlock() и mutex(). Использование этих методов вне потока совместно с needLockRun(true) поможет защитить данные.

Перечисления

◆ Priority

Приоритет потока

Элементы перечислений
piLowerst 

Низший

piLow 

Низкий

piNormal 

Нормальный, это приоритет по умолчанию для потоков и таймеров

piHigh 

Высокий

piHighest 

Высший

Методы

◆ startOnce() [1/2]

bool PIThread::startOnce ( )

Запускает поток без внутреннего цикла

Начинает выполнение run() один раз. Также поток вызывает внешний метод, заданный через setSlot(), если он существует.

Возвращает
false если поток уже запущен или не может запуститься

◆ startOnce() [2/2]

bool PIThread::startOnce ( ThreadFunc  func)

Запускает поток без внутреннего цикла

Перегрузка метода, устанавливает внешний метод в "func" перед запуском.

Возвращает
false если поток уже запущен или не может запуститься

◆ stop()

void PIThread::stop ( )

Останавливает поток

Помечает поток на остановку и ожидает завершения если "wait" true. Поток может быть остановлен только вне run() или внешнего метода.

Предупреждения
Этот метод может ожидать бесконечно если "wait" true и любой из потоковых методов занят навечно.

◆ terminate()

void PIThread::terminate ( )

Жёстко прерывает поток

Немедленно останавливает поток.

Предупреждения
Это может повредить память, старайтесь не использовать этот метод!

◆ waitForStart()

bool PIThread::waitForStart ( int  timeout_msecs = -1)
inline

Блокирует до тех пор, пока поток не запустится в течении "timeout_msecs", или бесконечно, если "timeout_msecs" < 0

Возвращает
true если поток запустился менее чем за таймаут
false если таймаут истёк

◆ waitForFinish()

bool PIThread::waitForFinish ( int  timeout_msecs = -1)
inline

Блокирует до тех пор, пока поток не завершится в течении "timeout_msecs", или бесконечно, если "timeout_msecs" < 0

Возвращает
true если поток завершился менее чем за таймаут
false если таймаут истёк

◆ runOnce() [1/2]

void PIThread::runOnce ( PIObject object,
const char *  handler,
const PIString name = PIString() 
)
static

Вызывает обработчик "handler" объекта "object" в отдельном потоке

Этот метод создает PIThread с именем "name" и выполняет обработчик "handler" объекта "object" в этом потоке.
PIThread автоматически удаляется после завершения обработчика.

class MyObj: public PIObject {
PIOBJECT(MyObj)
public:
EVENT_HANDLER(void, threadRun) {
piForTimes (5) {
piCout << "threadRun";
piMSleep(100);
}
};
};
int main(int argc, char * argv[]) {
MyObj mo;
PIThread::runOnce(&mo, "threadRun");
piMSleep(1000); // wait for thread finish
return 0;
}
static void runOnce(PIObject *object, const char *handler, const PIString &name=PIString())
Вызывает обработчик "handler" объекта "object" в отдельном потоке
Definition: pithread.cpp:1005

◆ runOnce() [2/2]

void PIThread::runOnce ( std::function< void()>  func,
const PIString name = PIString() 
)
static

Вызывает лямбда-выражение "func" в отдельном потоке

Этот метод создает PIThread с именем "name" и выполняет лямбда-выражение "func" в этом потоке.
PIThread автоматически удаляется после завершения функции.
"func" не должна иметь аргументов.

piCout << "thread func";
piMSleep(100);
}
});
piMSleep(1000);