* PIThread::~PIThread() now unregister itself from introspection, if terminates than show warning * PISystemMonitor now correctly stops * PIPeer now can correctly stopAndWait * PIPeer::destroy(), protected method for close all eths and threads * new PIINTROSPECTION_STOP macro * Introspection now can be correctly stopped by macro, more safety ClientServer: * ClientBase::close() stop and disconnect channel * Server clients clean-up now event-based * No warnings on client destructor
132 lines
4.6 KiB
C++
132 lines
4.6 KiB
C++
/*
|
||
PIP - Platform Independent Primitives
|
||
Class for simply notify and wait in different threads
|
||
Andrey Bychkov work.a.b@yandex.ru
|
||
|
||
This program is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
This program is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#include "pithreadnotifier.h"
|
||
|
||
//! \addtogroup Thread
|
||
//! \{
|
||
//! \class PIThreadNotifier pithreadnotifier.h
|
||
//!
|
||
//! \~\brief
|
||
//! \~english Class for simple notify and wait in different threads
|
||
//! \~russian Класс для простого уведомления и ожидания в различных потоках
|
||
//!
|
||
//! \~\details
|
||
//! \~english \section PIThreadNotifier_sec0 Synopsis
|
||
//! \~russian \section PIThreadNotifier_sec0 Краткий обзор
|
||
//! \~english
|
||
//! This class used as event mechanism between threads. One thread wait for some event,
|
||
//! and another send this event, unblocking first thread. It is useful to
|
||
//! syncronize some actions in several threads.
|
||
//!
|
||
//! \~russian
|
||
//! Этот класс используется как событийный механизм между потоками.
|
||
//! Один поток ждёт некоторого события и другой его отправляет, разблокируя первый.
|
||
//! Это полезно для синхронизации действий в нескольких потоках.
|
||
//!
|
||
//! \~english \section PIThreadNotifier_sec1 Usage
|
||
//! \~russian \section PIThreadNotifier_sec1 Использование
|
||
//! \~\code
|
||
//! PIThreadNotifier notifier;
|
||
//! PITimeMeasurer time;
|
||
//!
|
||
//! class Worker: public PIThread {
|
||
//! PIOBJECT_SUBCLASS(Worker, PIThread)
|
||
//! public:
|
||
//! Worker(const PIString & n) {
|
||
//! setName(n);
|
||
//! }
|
||
//! void run() override {
|
||
//! piCoutObj << (int)time.elapsed_m() << "wait ...";
|
||
//! notifier.wait();
|
||
//! piCoutObj << (int)time.elapsed_m() << "done";
|
||
//! };
|
||
//! };
|
||
//!
|
||
//!
|
||
//! int main(int argc, char * argv[]) {
|
||
//! PIVector<Worker*> workers;
|
||
//!
|
||
//! // create 2 threads
|
||
//! for (auto n: {"first ", "second"})
|
||
//! workers << new Worker(n);
|
||
//!
|
||
//! // start them
|
||
//! for (auto * w: workers)
|
||
//! w->startOnce();
|
||
//!
|
||
//! piMSleep(500);
|
||
//! notifier.notify(); // notify one of them after 500 ms
|
||
//! piMSleep(500);
|
||
//! notifier.notify(); // notify one of them after 1000 ms
|
||
//!
|
||
//! for (auto * w: workers)
|
||
//! w->waitForFinish();
|
||
//! }
|
||
//!
|
||
//! // [Worker "first "] 0 wait ...
|
||
//! // [Worker "second"] 0 wait ...
|
||
//! // [Worker "second"] 500 done
|
||
//! // [Worker "first "] 1000 done
|
||
//! \endcode
|
||
//! \}
|
||
|
||
|
||
PIThreadNotifier::PIThreadNotifier(): cnt(0) {}
|
||
|
||
|
||
//! \~\details
|
||
//! \~english
|
||
//! If \a notify() has been called before, then returns immediately.\n
|
||
//! If \a notify() has been called "n" times, then returns immediately "n" times,
|
||
//! but only if wait in one thread.\n
|
||
//! If many threads waiting, then if \a notify() has been called "n" times,
|
||
//! all threads total returns "n" times in undefined sequence.
|
||
//!
|
||
//! \~russian
|
||
//! Если ранее был вызван \a notify(), то возвращает управление немедленно.\n
|
||
//! Если ранее был вызван \a notify() "n" раз, то возвращает управление немедленно "n" раз,
|
||
//! но только если ожидать одним потоком.\n
|
||
//! Если ожидают несколько потоков, и \a notify() был вызван "n" раз,
|
||
//! то все потоки суммарно вернут управление "n" раз в неопределенной последовательности.
|
||
//!
|
||
void PIThreadNotifier::wait() {
|
||
m.lock();
|
||
while (cnt == 0)
|
||
v.wait(m);
|
||
cnt--;
|
||
m.unlock();
|
||
}
|
||
|
||
|
||
//! \~\details
|
||
//! \~english
|
||
//! 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::notify() {
|
||
m.lock();
|
||
cnt++;
|
||
v.notifyAll();
|
||
m.unlock();
|
||
}
|