thread doc ru
This commit is contained in:
@@ -31,13 +31,20 @@
|
||||
//! \~russian \section PIMutex_sec0 Краткий обзор
|
||||
//!
|
||||
//! \~english
|
||||
//! %PIMutex provides synchronization blocks between several threads.
|
||||
//! %PIMutex provides critical code section defence between several threads.
|
||||
//! Using mutex guarantees execution of some code only one of threads.
|
||||
//! Mutex contains logic state and functions to change it: \a lock(),
|
||||
//! \a unlock() and \a tryLock().
|
||||
//!
|
||||
//! \~russian
|
||||
//! For automatic lock-unlock use \a PIMutexLocker.
|
||||
//!
|
||||
//! \~russian
|
||||
//! %PIMutex предоставляет межпотоковую защиту критических секций кода.
|
||||
//! Использование мьютекса гарантирует выполнение секции только один потоком.
|
||||
//! Мьютекс состоит из логического состояния и методов для его изменения:
|
||||
//! \a lock(), \a unlock() and \a tryLock().
|
||||
//!
|
||||
//! Для автоматической блокировки-разблокировки используйте \a PIMutexLocker.
|
||||
//!
|
||||
//! \~english \section PIMutex_sec1 Usage
|
||||
//! \~russian \section PIMutex_sec1 Использование
|
||||
@@ -47,11 +54,15 @@
|
||||
//! should to be started with \a lock() and finished with \a unlock().
|
||||
//!
|
||||
//! \~russian
|
||||
//! Части кода, которые должны быть выполнены только одним потоком в любой момент
|
||||
//! времени должны начинаться с вызова \a lock() и заканчиваться вызовом \a unlock().
|
||||
//!
|
||||
//! \~\code
|
||||
//! // critical section start
|
||||
//! mutex.lock();
|
||||
//! // ... your code here
|
||||
//! mutex.unlock();
|
||||
//! // critical section end
|
||||
//! \endcode
|
||||
//! \}
|
||||
|
||||
@@ -68,14 +79,31 @@
|
||||
//! \~\details
|
||||
//!
|
||||
//! \~english
|
||||
//! When a PIMutexLocker object is created, it attempts to lock the mutex it is given, if "condition" true.
|
||||
//! When control leaves the scope in which the PIMutexLocker object was created,
|
||||
//! the PIMutexLocker is destructed and the mutex is released, if "condition" true.
|
||||
//! If "condition" false this class do nothing.
|
||||
//! The PIMutexLocker class is non-copyable.
|
||||
//! When a %PIMutexLocker object is created, it attempts to lock the mutex it is given, if "condition" \c true.
|
||||
//! When control leaves the scope in which the %PIMutexLocker object was created,
|
||||
//! the %PIMutexLocker is destructed and the mutex is released, if "condition" was \c true.
|
||||
//!
|
||||
//! If "condition" \c false this class do nothing.
|
||||
//!
|
||||
//! The %PIMutexLocker class is non-copyable.
|
||||
//!
|
||||
//! \~russian
|
||||
//! При создании экземпляра %PIMutexLocker блокируется переданный мьютекс, если "condition" \c true.
|
||||
//! Когда выполнение покидает область жизни объекта, вызывается его деструктор и мьютекс
|
||||
//! разблокируется, если "condition" был \c true.
|
||||
//!
|
||||
//! Если "condition" \c false, то этот объект ничего не делает.
|
||||
//!
|
||||
//! Класс %PIMutexLocker некопируемый.
|
||||
//!
|
||||
//! \~\code
|
||||
//! // critical section start
|
||||
//! {
|
||||
//! PIMutexLocker locker(mutex);
|
||||
//! // ... your code here
|
||||
//! }
|
||||
//! // critical section end
|
||||
//! \endcode
|
||||
//! \}
|
||||
|
||||
|
||||
@@ -118,6 +146,8 @@ PIMutex::~PIMutex() {
|
||||
//! If mutex is unlocked it set to locked state and returns immediate.
|
||||
//! If mutex is already locked function blocks until mutex will be unlocked
|
||||
//! \~russian
|
||||
//! Если мьютекс свободен, то блокирует его и возвращает управление немедленно.
|
||||
//! Если мьютекс заблокирован, то ожидает разблокировки, затем блокирует и возвращает управление
|
||||
void PIMutex::lock() {
|
||||
#if defined(WINDOWS)
|
||||
EnterCriticalSection(&(PRIVATE->mutex));
|
||||
@@ -133,6 +163,7 @@ void PIMutex::lock() {
|
||||
//! \~english
|
||||
//! In any case this function returns immediate
|
||||
//! \~russian
|
||||
//! В любом случае возвращает управление немедленно
|
||||
void PIMutex::unlock() {
|
||||
#if defined(WINDOWS)
|
||||
LeaveCriticalSection(&(PRIVATE->mutex));
|
||||
|
||||
@@ -72,11 +72,11 @@ public:
|
||||
NO_COPY_CLASS(PIMutexLocker)
|
||||
|
||||
//! \~english Constructs and lock "m" if "condition" is \c true
|
||||
//! \~russian
|
||||
//! \~russian Создает и блокирует мьютекс "m" если "condition" \c true
|
||||
PIMutexLocker(PIMutex & m, bool condition = true): mutex(m), cond(condition) {if (cond) mutex.lock();}
|
||||
|
||||
//! \~english Unlock "m" if "condition" was \c true
|
||||
//! \~russian
|
||||
//! \~russian Разблокирует мьютекс "m" если "condition" был \c true
|
||||
~PIMutexLocker() {if (cond) mutex.unlock();}
|
||||
|
||||
private:
|
||||
|
||||
@@ -27,11 +27,18 @@
|
||||
//!
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! %PISpinlock provides synchronization blocks between several threads.
|
||||
//! PISpinlock functionality similar to PIMutex, but working on atomic
|
||||
//! type and \a lock() method wait with 100% CPU load.
|
||||
//! %PISpinlock provides critical code section defence between several threads.
|
||||
//! %PISpinlock functionality similar to PIMutex, but working on atomic
|
||||
//! type and \a lock() method wait with 100% CPU core load.
|
||||
//!
|
||||
//! For automatic lock-unlock use \a PISpinlockLocker.
|
||||
//!
|
||||
//! \~russian
|
||||
//! %PISpinlock предоставляет межпотоковую защиту критических секций кода.
|
||||
//! Функционально он аналогичен PIMutex, однако работает на атомарном типе
|
||||
//! и ожидание разблокировки в методе \a lock() нагружает ядро ЦП на 100%.
|
||||
//!
|
||||
//! Для автоматической блокировки-разблокировки используйте \a PISpinlockLocker.
|
||||
//!
|
||||
//! \~\note
|
||||
//! \~english
|
||||
@@ -39,6 +46,8 @@
|
||||
//! important than CPU load!
|
||||
//!
|
||||
//! \~russian
|
||||
//! Используйте этот класс вместо PIMutex когда время ожидания гораздо важнее
|
||||
//! чем нагрузка на ЦП!
|
||||
//!
|
||||
//! \}
|
||||
|
||||
@@ -49,17 +58,26 @@
|
||||
//!
|
||||
//! \~\brief
|
||||
//! \~english %PISpinlock autolocker
|
||||
//! \~russian
|
||||
//! \~russian Автоблокировщик %PISpinlock
|
||||
//!
|
||||
//!
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! When a PISpinlockLocker object is created, it attempts to lock the spinlock it is given, if "condition" true.
|
||||
//! When control leaves the scope in which the PISpinlockLocker object was created,
|
||||
//! the PISpinlockLocker is destructed and the spinlock is released, if "condition" true.
|
||||
//! When a %PISpinlockLocker object is created, it attempts to lock the spinlock it is given, if "condition" true.
|
||||
//! When control leaves the scope in which the %PISpinlockLocker object was created,
|
||||
//! the %PISpinlockLocker is destructed and the spinlock is released, if "condition" true.
|
||||
//!
|
||||
//! If "condition" false this class do nothing.
|
||||
//! The PISpinlockLocker class is non-copyable.
|
||||
//!
|
||||
//! The %PISpinlockLocker class is non-copyable.
|
||||
//!
|
||||
//! \~russian
|
||||
//! При создании экземпляра %PISpinlockLocker блокируется переданный спинлок, если "condition" \c true.
|
||||
//! Когда выполнение покидает область жизни объекта, вызывается его деструктор и спинлок
|
||||
//! разблокируется, если "condition" был \c true.
|
||||
//!
|
||||
//! Если "condition" \c false, то этот объект ничего не делает.
|
||||
//!
|
||||
//! Класс %PISpinlockLocker некопируемый.
|
||||
//!
|
||||
//! \}
|
||||
|
||||
@@ -36,29 +36,32 @@ public:
|
||||
NO_COPY_CLASS(PISpinlock)
|
||||
|
||||
//! \~english Constructs unlocked spinlock
|
||||
//! \~russian
|
||||
//! \~russian Создает незаблокированный спинлок
|
||||
explicit PISpinlock() {flag.clear();}
|
||||
|
||||
//! \~english Destroy spinlock
|
||||
//! \~russian
|
||||
//! \~russian Деструктор спинлока
|
||||
~PISpinlock() {}
|
||||
|
||||
|
||||
//! \~english Lock spinlock
|
||||
//! \~russian
|
||||
//! \~russian Блокирует спинлок
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! If spinlock is unlocked it set to locked state and returns immediate.
|
||||
//! If spinlock is already locked function blocks until spinlock will be unlocked
|
||||
//! \~russian
|
||||
//! Если спинлок свободен, то блокирует его и возвращает управление немедленно.
|
||||
//! Если спинлок заблокирован, то ожидает разблокировки, затем блокирует и возвращает управление
|
||||
void lock() {while (flag.test_and_set(std::memory_order_acquire));}
|
||||
|
||||
//! \~english Unlock spinlock
|
||||
//! \~russian
|
||||
//! \~russian Разблокирует спинлок
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! In any case this function returns immediate
|
||||
//! \~russian
|
||||
//! В любом случае возвращает управление немедленно
|
||||
void unlock() {flag.clear(std::memory_order_release);}
|
||||
|
||||
private:
|
||||
@@ -73,11 +76,11 @@ public:
|
||||
NO_COPY_CLASS(PISpinlockLocker)
|
||||
|
||||
//! \~english Constructs and lock "s" if "condition" is \c true
|
||||
//! \~russian
|
||||
//! \~russianСоздает и блокирует спинлок "m" если "condition" \c true
|
||||
PISpinlockLocker(PISpinlock & s, bool condition = true): spinlock(s), cond(condition) {if (cond) spinlock.lock();}
|
||||
|
||||
//! \~english Unlock "s" if "condition" was \c true
|
||||
//! \~russian
|
||||
//! \~russian Разблокирует спинлок "m" если "condition" был \c true
|
||||
~PISpinlockLocker() {if (cond) spinlock.unlock();}
|
||||
|
||||
private:
|
||||
|
||||
@@ -72,30 +72,62 @@ __THREAD_FUNC_RET__ thread_function_once(void * t) {((PIThread*)t)->__thread_fun
|
||||
//! \~english \section PIThread_sec0 Synopsis
|
||||
//! \~russian \section PIThread_sec0 Краткий обзор
|
||||
//! \~english
|
||||
//! Multithreading allow you to write program which will be executed
|
||||
//! Multithreading allow you to execute code
|
||||
//! in several threads simultaneously. This trend allow you to use all
|
||||
//! cores of modern processors, but there are many dangers.
|
||||
//!
|
||||
//! This class provide virtual functions \a begin(), \a run() and \a end(),
|
||||
//! which describes start, execution and finish work of some process.
|
||||
//! These functions executes in \b separate thread. When you execute
|
||||
//! \a start(), %PIThread create separate system thread and sequentially
|
||||
//! \a start(int), %PIThread create separate system thread and sequentially
|
||||
//! executes function \a begin(), \a run() and \a end(). You can
|
||||
//! reimplement each function and write your own code to execute.
|
||||
//!
|
||||
//! Scheme of functions executing:
|
||||
//!
|
||||
//! \~russian
|
||||
//! Многопоточность позволяет исполнять код в нескольких потоках
|
||||
//! одновременно и использовать все ядра современных процессоров.
|
||||
//! Однако это таит в себе опасности.
|
||||
//!
|
||||
//! Этот класс предоставляет виртуальные методы \a begin(), \a run() и \a end(),
|
||||
//! которые описывают старт, выполнение и завершение потоковой задачи.
|
||||
//! Все эти методы исполняются в \b отдельном потоке. Когда выполняется
|
||||
//! \a start(int), %PIThread создает отдельный поток средствами ОС и последовательно
|
||||
//! выполняет \a begin(), \a run() и \a end(). Можно переопределить каждый метод
|
||||
//! для реализации нужной задачи.
|
||||
//!
|
||||
//! Схема выполнения методов:
|
||||
//!
|
||||
//! \~\code{.cpp}
|
||||
//! begin();
|
||||
//! event started();
|
||||
//! while (isRunning()) {
|
||||
//! run();
|
||||
//! ThreadFunc();
|
||||
//! piMSleep(timer_delay);
|
||||
//! virtual begin()
|
||||
//! event started()
|
||||
//! while (isRunning()) { // while not stop()
|
||||
//! virtual run()
|
||||
//! ThreadFunc() // Slot or lambda
|
||||
//! piMSleep(timer_delay) // if timer_delay > 0
|
||||
//! }
|
||||
//! event stopped();
|
||||
//! end();
|
||||
//! event stopped()
|
||||
//! virtual end()
|
||||
//! \endcode
|
||||
//!
|
||||
//! \~english
|
||||
//! If no internal loop needed, you can use \a startOnce() method instead of \a start(int).
|
||||
//!
|
||||
//! In this case scheme is next:
|
||||
//!
|
||||
//! \~russian
|
||||
//! Если внутренний цикл не нужен, то можно использовать метод \a startOnce() вместо \a start(int).
|
||||
//!
|
||||
//! В этом случает схема выполнения следущая:
|
||||
//!
|
||||
//! \~\code{.cpp}
|
||||
//! virtual begin()
|
||||
//! event started()
|
||||
//! virtual run()
|
||||
//! ThreadFunc() // Slot or lambda
|
||||
//! event stopped()
|
||||
//! virtual end()
|
||||
//! \endcode
|
||||
//!
|
||||
//! \~english
|
||||
@@ -106,6 +138,67 @@ __THREAD_FUNC_RET__ thread_function_once(void * t) {((PIThread*)t)->__thread_fun
|
||||
//! and \a end() functions.
|
||||
//!
|
||||
//! \~russian
|
||||
//! В отличии от прямого использования "pthread" или похожих механизмов
|
||||
//! нет необходимости писать свой цикл внутри поточного метода и ожидать
|
||||
//! в его теле. %PIThread уже рализует такой цикл, необходимо лишь
|
||||
//! установить значение ожидания в конструкторе или при запуске потока,
|
||||
//! и переопределить методы \a begin(), \a run() и \a end().
|
||||
//!
|
||||
//! \~english Using with internal loop
|
||||
//! \~russian Использование с внутренним циклом
|
||||
//! \~\code{.cpp}
|
||||
//! 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
|
||||
//! \endcode
|
||||
//!
|
||||
//! \~english Using without internal loop
|
||||
//! \~russian Использование без внутреннего цикла
|
||||
//! \~\code{.cpp}
|
||||
//! 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
|
||||
//! \endcode
|
||||
//!
|
||||
//!
|
||||
//! \~english \section PIThread_sec1 Using without subclassing
|
||||
@@ -113,27 +206,243 @@ __THREAD_FUNC_RET__ thread_function_once(void * t) {((PIThread*)t)->__thread_fun
|
||||
//! \~english
|
||||
//! You can use %PIThread without subclassing by using "ThreadFunc" pointer
|
||||
//! that can be set from constructor or by overloaded function \a start(ThreadFunc func, int timer_delay).
|
||||
//! If "func" if not null this function will be executed as \a run(). ThreadFunc is any static
|
||||
//! function with format void func(void * data). "Data" is custom data set from constructor or
|
||||
//! with function \a setData(). \n Also you can connect to event \a started(), but
|
||||
//! in this case you should to white your thread main cycle, because this event raised only one time.
|
||||
//! If "func" if not null this function will be executed after \a run().
|
||||
//!
|
||||
//! ThreadFunc is any static function with format "void func(void * data)", or
|
||||
//! lambda-function with format [...]( ){...}.
|
||||
//! "Data" is custom data set from constructor or with \a setData() function.
|
||||
//!
|
||||
//! Also you can connect to event \a started(), but in this case you should to white
|
||||
//! your thread main cycle, because this event raised only one time after thread start.
|
||||
//!
|
||||
//! \~russian
|
||||
//! Возможно использовать %PIThread без наследования. Можно передать ему в конструкторе
|
||||
//! или при запуске указатель на внешний метод "ThreadFunc". В основном цикле потока,
|
||||
//! если "ThreadFunc" существует, он будет вызываться после \a run().
|
||||
//!
|
||||
//! ThreadFunc может быть любым статическим методом в формате "void func(void * data)", либо
|
||||
//! лямбда-функцией в формате [...]( ){...}.
|
||||
//! "Data" является произвольным указателем, задаваемым в конструкторе или методом \a setData().
|
||||
//!
|
||||
//! Также можно присоединиться к событию \a started(), но в этом случае надо будет своими силами
|
||||
//! реализовать весь цикл, т.к. это событие вызывается один раз после запуска потока.
|
||||
//!
|
||||
//! \~english Using with internal loop
|
||||
//! \~russian Использование с внутренним циклом
|
||||
//! \~\code{.cpp}
|
||||
//! void myThreadFunc(void * d) {
|
||||
//! int * cnt = (int*)d;
|
||||
//! piCout << "thread run" << ++(*cnt);
|
||||
//! }
|
||||
//!
|
||||
//! int main(int argc, char * argv[]) {
|
||||
//! int cnt = 0;
|
||||
//! PIThread mt;
|
||||
//! 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
|
||||
//! \endcode
|
||||
//!
|
||||
//! \~english Using without internal loop
|
||||
//! \~russian Использование без внутреннего цикла
|
||||
//! \~\code{.cpp}
|
||||
//! void myThreadFunc(void * d) {
|
||||
//! int * cnt = (int*)d;
|
||||
//! piCout << "thread run" << ++(*cnt);
|
||||
//! }
|
||||
//!
|
||||
//! int main(int argc, char * argv[]) {
|
||||
//! int cnt = 0;
|
||||
//! PIThread mt;
|
||||
//! mt.setData(&cnt);
|
||||
//! mt.startOnce(myThreadFunc);
|
||||
//! piMSleep(500);
|
||||
//! mt.stop(true);
|
||||
//! return 0;
|
||||
//! }
|
||||
//!
|
||||
//! // thread run 1
|
||||
//! \endcode
|
||||
//!
|
||||
//! \~english Using with lambda-function
|
||||
//! \~russian Использование с лямбда-функцией
|
||||
//! \~\code{.cpp}
|
||||
//! int main(int argc, char * argv[]) {
|
||||
//! int cnt = 0;
|
||||
//! PIThread mt;
|
||||
//! 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
|
||||
//! \endcode
|
||||
//!
|
||||
//! \~english Using with event
|
||||
//! \~russian Использование с событием
|
||||
//! \~\code{.cpp}
|
||||
//! 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;
|
||||
//! PIThread mt;
|
||||
//! CONNECTU(&mt, started, &mo, threadRun);
|
||||
//! mt.startOnce();
|
||||
//! mt.stop(true);
|
||||
//! return 0;
|
||||
//! }
|
||||
//!
|
||||
//! // threadRun 1
|
||||
//! // threadRun 2
|
||||
//! // threadRun 3
|
||||
//! // threadRun 4
|
||||
//! // threadRun 5
|
||||
//! \endcode
|
||||
//!
|
||||
//! \~english \section PIThread_sec2 Locking
|
||||
//! \~russian \section PIThread_sec2 Блокировки
|
||||
//! \~english
|
||||
//! %PIThread has inrternal mutex that can be locked and unlocked every \a run() if you set this flag
|
||||
//! with function \a needLockRun(bool). Also you can access to this mutex by functions \a lock(), \a unlock()
|
||||
//! and \a mutex(). Using this functions together with needLockRun(true) can guarantee one-thread access to
|
||||
//! some data.
|
||||
//! with function \a needLockRun(true). Also you can access to this mutex by functions \a lock(), \a unlock()
|
||||
//! and \a mutex(). Using this functions outside of thread together with \a needLockRun(true) can defend
|
||||
//! your data.
|
||||
//!
|
||||
//! \~russian
|
||||
//! %PIThread имеет встроенный мьютекс, который может блокироваться и разблокироваться каждый \a run()
|
||||
//! при установленном \a needLockRun(true). К нему есть доступ через методы \a lock(), \a unlock() и \a mutex().
|
||||
//! Использование этих методов вне потока совместно с \a needLockRun(true) поможет защитить данные.
|
||||
//!
|
||||
//! \}
|
||||
//!
|
||||
|
||||
|
||||
//! \fn bool PIThread::start(int timer_delay = -1)
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! Start execution of \a run() in internal loop with
|
||||
//! "timer_delay" delay in milliseconds. If "timer_delay" <= 0
|
||||
//! this is no delay in loop. Thread also exec external function
|
||||
//! set by \a setSlot() if it`s not null.
|
||||
//! \return \c false if thread already started or can`t start thread
|
||||
//!
|
||||
//! \~russian
|
||||
//! Начинает выполнение \a run() во внутреннем цикле
|
||||
//! с задержкой "timer_delay" миллисекунд. Если "timer_delay" <= 0
|
||||
//! то задержки не будет. Также поток вызывает внешний метод,
|
||||
//! заданный через \a setSlot(), если он существует.
|
||||
//! \return \c false если поток уже запущен или не может запуститься
|
||||
|
||||
|
||||
//! \fn bool PIThread::startOnce()
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! Start execution of \a run() once. Thread also exec
|
||||
//! external function set by \a setSlot() if it`s not null.
|
||||
//! \return \c false if thread already started or can`t start thread
|
||||
//!
|
||||
//! \~russian
|
||||
//! Начинает выполнение \a run() один раз. Также поток вызывает
|
||||
//! внешний метод, заданный через \a setSlot(), если он существует.
|
||||
//! \return \c false если поток уже запущен или не может запуститься
|
||||
|
||||
|
||||
//! \fn bool PIThread::startOnce(ThreadFunc func)
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! Overloaded function. Set external function "func" before start.
|
||||
//! \return \c false if thread already started or can`t start thread
|
||||
//!
|
||||
//! \~russian
|
||||
//! Перегрузка метода, устанавливает внешний метод в "func" перед запуском.
|
||||
//! \return \c false если поток уже запущен или не может запуститься
|
||||
|
||||
|
||||
//! \fn void PIThread::stop(bool wait = false)
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! Mark thread to stop execution and wait for finish
|
||||
//! if "wait" is \c true. Thread can be stopped only outside of
|
||||
//! \a run() or external method.
|
||||
//! \warning This function can block for infinite
|
||||
//! time if "wait" is \c true and any of thread function is
|
||||
//! busy forever.
|
||||
//!
|
||||
//! \~russian
|
||||
//! Помечает поток на остановку и ожидает завершения если
|
||||
//! "wait" \c true. Поток может быть остановлен только вне
|
||||
//! \a run() или внешнего метода.
|
||||
//! \warning Этот метод может ожидать бесконечно если
|
||||
//! "wait" \c true и любой из потоковых методов занят навечно.
|
||||
|
||||
|
||||
//! \fn void PIThread::terminate()
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! Stop execution of thread immediately.
|
||||
//! \warning Memory can be corrupted, try not to use this method!
|
||||
//!
|
||||
//! \~russian
|
||||
//! Немедленно останавливает поток.
|
||||
//! \warning Это может повредить память, старайтесь не использовать этот метод!
|
||||
|
||||
|
||||
//! \fn bool PIThread::waitForStart(int timeout_msecs = -1)
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! Block until thread start within "timeout_msecs"
|
||||
//! or forever if "timeout_msecs" < 0
|
||||
//! \return \c true if thread started less than timeout
|
||||
//! \return \c false if timeout is exceeded
|
||||
//!
|
||||
//! \~russian
|
||||
//! Блокирует до тех пор, пока поток не запустится в течении
|
||||
//! "timeout_msecs", или бесконечно, если "timeout_msecs" < 0
|
||||
//! \return \c true если поток запустился менее чем за таймаут
|
||||
//! \return \c false если таймаут истёк
|
||||
|
||||
|
||||
//! \fn bool PIThread::waitForFinish(int timeout_msecs = -1)
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! Block until thread finish for "timeout_msecs"
|
||||
//! or forever if "timeout_msecs" < 0
|
||||
//! \return \c true if thread finished less than timeout
|
||||
//! \return \c false if timeout is exceeded
|
||||
//!
|
||||
//! \~russian
|
||||
//! Блокирует до тех пор, пока поток не завершится в течении
|
||||
//! "timeout_msecs", или бесконечно, если "timeout_msecs" < 0
|
||||
//! \return \c true если поток завершился менее чем за таймаут
|
||||
//! \return \c false если таймаут истёк
|
||||
|
||||
|
||||
#ifndef MICRO_PIP
|
||||
|
||||
__PIThreadCollection *__PIThreadCollection::instance() {
|
||||
@@ -614,6 +923,36 @@ void PIThread::__thread_func_once__() {
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! This method create %PIThread with name "name" and execute
|
||||
//! event handler "handler" of object "object" in this thread.\n
|
||||
//! This %PIThread automatically delete on function finish.
|
||||
//!
|
||||
//! \~russian
|
||||
//! Этот метод создает %PIThread с именем "name" и выполняет
|
||||
//! обработчик "handler" объекта "object" в этом потоке.\n
|
||||
//! %PIThread автоматически удаляется после завершения обработчика.
|
||||
//!
|
||||
//! \~\code
|
||||
//! 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;
|
||||
//! }
|
||||
//! \endcode
|
||||
void PIThread::runOnce(PIObject * object, const char * handler, const PIString & name) {
|
||||
PIThread * t = new PIThread();
|
||||
t->setName(name);
|
||||
@@ -629,6 +968,28 @@ void PIThread::runOnce(PIObject * object, const char * handler, const PIString &
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! This method create %PIThread with name "name" and execute
|
||||
//! lambda-function "func" in this thread.\n
|
||||
//! This %PIThread automatically delete on function finish.\n
|
||||
//! "func" shouldn`t have arguments.
|
||||
//!
|
||||
//! \~russian
|
||||
//! Этот метод создает %PIThread с именем "name" и выполняет
|
||||
//! лямбда-функцию "func" в этом потоке.\n
|
||||
//! %PIThread автоматически удаляется после завершения функции.\n
|
||||
//! "func" не должна иметь аргументов.
|
||||
//!
|
||||
//! \~\code
|
||||
//! PIThread::runOnce([](){
|
||||
//! piForTimes(5) {
|
||||
//! piCout << "thread func";
|
||||
//! piMSleep(100);
|
||||
//! }
|
||||
//! });
|
||||
//! piMSleep(1000);
|
||||
//! \endcode
|
||||
void PIThread::runOnce(std::function<void ()> func, const PIString & name) {
|
||||
PIThread * t = new PIThread();
|
||||
t->setName(name);
|
||||
|
||||
@@ -169,19 +169,12 @@ public:
|
||||
EVENT(started)
|
||||
EVENT(stopped)
|
||||
|
||||
//! \~english
|
||||
//! Start event handler with name "handler" of object "object"
|
||||
//! in separate thread with name "name"
|
||||
//! and automatically delete it on function finish
|
||||
//!
|
||||
//! \~russian
|
||||
//! \~english Call event handler "handler" of object "object" in separate thread
|
||||
//! \~russian Вызывает обработчик "handler" объекта "object" в отдельном потоке
|
||||
static void runOnce(PIObject * object, const char * handler, const PIString & name = PIString());
|
||||
|
||||
//! \~english
|
||||
//! Start function "func" in separate thread with name "name"
|
||||
//! and automatically delete it on function finish
|
||||
//!
|
||||
//! \~russian
|
||||
//! \~english Call lambda-function "func" in separate thread
|
||||
//! \~russian Вызывает лямбда-функцию "func" в отдельном потоке
|
||||
static void runOnce(std::function<void()> func, const PIString & name = PIString());
|
||||
|
||||
//! \handlers
|
||||
@@ -190,72 +183,30 @@ public:
|
||||
//! \fn bool start(int timer_delay = -1)
|
||||
//! \~english Start thread
|
||||
//! \~russian Запускает поток
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! Start execution of \a run() in internal loop with
|
||||
//! "timer_delay" delay in milliseconds. If "timer_delay" <= 0
|
||||
//! there is no delay in loop. Thread also exec external function
|
||||
//! set by \a setSlot() if it`s not null
|
||||
//! \return \c false if thread already started or can`t start thread
|
||||
//! \~russian
|
||||
|
||||
//! \fn bool startOnce()
|
||||
//! \~english Start thread without internal loop
|
||||
//! \~russian Запускает поток без внутреннего цикла
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! Start execution of \a run() once. Thread also exec
|
||||
//! external function set by \a setSlot() if it`s not null
|
||||
//! \return \c false if thread already started or can`t start thread
|
||||
//! \~russian
|
||||
|
||||
//! \fn bool startOnce(ThreadFunc func)
|
||||
//! \~english Start thread without internal loop
|
||||
//! \~russian Запускает поток без внутреннего цикла
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! Overloaded function. Set external function "func" before start
|
||||
//! \return \c false if thread already started or can`t start thread
|
||||
//! \~russian
|
||||
|
||||
//! \fn void stop(bool wait = false)
|
||||
//! \~english Stop thread
|
||||
//! \~russian Останавливает поток
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! Stop execution of thread and wait for it finish
|
||||
//! if "wait" is \c true. This function can block for infinite
|
||||
//! time if "wait" is \c true and any of thread function is
|
||||
//! busy forever
|
||||
//! \~russian
|
||||
|
||||
//! \fn void terminate()
|
||||
//! \~english Strongly stop thread
|
||||
//! \~russian Жестко останавливает поток
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! Stop execution of thread immediately
|
||||
//! \~russian
|
||||
|
||||
//! \fn bool waitForStart(int timeout_msecs = -1)
|
||||
//! \~english Wait for thread start
|
||||
//! \~russian Ожидает старта потока
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! This function block until thread start for "timeout_msecs"
|
||||
//! or forever if "timeout_msecs" < 0
|
||||
//! \return \c false if timeout is exceeded
|
||||
//! \~russian
|
||||
|
||||
//! \fn bool waitForFinish(int timeout_msecs = -1)
|
||||
//! \~english Wait for thread finish
|
||||
//! \~russian Ожидает завершения потока
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! This function block until thread finish for "timeout_msecs"
|
||||
//! or forever if "timeout_msecs" < 0
|
||||
//! \return \c false if timeout is exceeded
|
||||
//! \~russian
|
||||
|
||||
//! \fn void lock()
|
||||
//! \~english Lock internal mutex
|
||||
|
||||
@@ -55,13 +55,18 @@ PIThreadNotifier::PIThreadNotifier() : cnt(0) {}
|
||||
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! If \a notifyOnce() has been called before, then returns immediately.
|
||||
//! If \a notifyOnce() has been called before, then returns immediately.\n
|
||||
//! If \a notifyOnce() has been called "n" times, then returns immediately "n" times,
|
||||
//! but only if wait in one thread.
|
||||
//! but only if wait in one thread.\n
|
||||
//! If many threads waiting, then if \a notifyOnce() has been called "n" times,
|
||||
//! all threads total returns "n" times in random sequence.
|
||||
//! all threads total returns "n" times in undefined sequence.
|
||||
//!
|
||||
//! \~russian
|
||||
//! Если ранее был вызван \a notifyOnce(), то возвращает управление немедленно.\n
|
||||
//! Если ранее был вызван \a notifyOnce() "n" раз, то возвращает управление немедленно "n" раз,
|
||||
//! но только если ожидать одним потоком.\n
|
||||
//! Если ожидают несколько потоков, и \a notifyOnce() был вызван "n" раз,
|
||||
//! то все потоки суммарно вернут управление "n" раз в неопределенной последовательности.
|
||||
//!
|
||||
void PIThreadNotifier::wait() {
|
||||
m.lock();
|
||||
@@ -73,10 +78,12 @@ void PIThreadNotifier::wait() {
|
||||
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! If many threads waiting, then notify randomly one.
|
||||
//! If many threads waiting, then notify randomly one.\n
|
||||
//! If call this "n" times, then notify any waiting threads totally "n" times.
|
||||
//!
|
||||
//! \~russian
|
||||
//! Если ожидают несколько потоков, то уведомляет один случайный.\n
|
||||
//! Если вызвать "n" раз, то все ожидающие потоки уведомятся суммарно "n" раз.
|
||||
void PIThreadNotifier::notifyOnce() {
|
||||
m.lock();
|
||||
cnt++;
|
||||
|
||||
Reference in New Issue
Block a user