Files
pip/libs/main/thread/pithreadnotifier.cpp
peri4 0dd47f50a0 version 4.6.0
PIThreadNotifier::waitFor() new method
PIThread::waitForFinish() now use condvar to exit as soon as possible
2025-01-15 17:57:16 +03:00

145 lines
4.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
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();
}
bool PIThreadNotifier::waitFor(PISystemTime timeout) {
bool ret = false;
m.lock();
v.waitFor(m, timeout);
if (cnt > 0) {
cnt--;
ret = true;
}
m.unlock();
return ret;
}
//! \~\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();
}