diff --git a/samples/blackmisc/main.cpp b/samples/blackmisc/main.cpp index f78b071c6..94a5abf55 100644 --- a/samples/blackmisc/main.cpp +++ b/samples/blackmisc/main.cpp @@ -15,6 +15,7 @@ #include "samplesvariant.h" #include "samplesperformance.h" #include "samplesalgorithm.h" +#include "samplesconcurrent.h" #include "blackmisc/blackmiscfreefunctions.h" #include "blackmisc/pqallquantities.h" @@ -26,25 +27,28 @@ using namespace BlackMiscTest; */ int main(int argc, char *argv[]) { - // QCoreApplication a(argc, argv); - Q_UNUSED(argc); - Q_UNUSED(argv); + QCoreApplication a(argc, argv);; + Q_UNUSED(a); + + QTextStream qtout(stdout); + QTextStream qtin(stdin); BlackMisc::initResources(); BlackMisc::registerMetadata(); do { - qDebug() << "1 .. JSON"; - qDebug() << "2 .. Change object"; - qDebug() << "3 .. Containers"; - qDebug() << "4 .. Metadata"; - qDebug() << "5 .. Variant"; - qDebug() << "6 .. Performance"; - qDebug() << "7 .. Algorithms"; - qDebug() << "-----"; - qDebug() << "x .. Bye"; - QTextStream qtin(stdin); + qtout << "1 .. JSON" << endl; + qtout << "2 .. Change object" << endl; + qtout << "3 .. Containers" << endl; + qtout << "4 .. Metadata" << endl; + qtout << "5 .. Variant" << endl; + qtout << "6 .. Performance" << endl; + qtout << "7 .. Algorithms" << endl; + qtout << "8 .. Concurrent (thread)" << endl; + + qtout << "-----" << endl; + qtout << "x .. Bye" << endl; QString s = qtin.readLine().toLower().trimmed(); if (s.startsWith("1")) { CSamplesJson::samples(); } @@ -54,6 +58,7 @@ int main(int argc, char *argv[]) else if (s.startsWith("5")) { CSamplesVariant::samples(); } else if (s.startsWith("6")) { CSamplesPerformance::samples(); } else if (s.startsWith("7")) { CSamplesAlgorithm::samples(); } + else if (s.startsWith("8")) { CSamplesConcurrent::samples(s, qtout, qtin); } else if (s.startsWith("x")) { break; } } while (true); diff --git a/samples/blackmisc/samplesconcurrent.cpp b/samples/blackmisc/samplesconcurrent.cpp new file mode 100644 index 000000000..54495393c --- /dev/null +++ b/samples/blackmisc/samplesconcurrent.cpp @@ -0,0 +1,103 @@ +/* Copyright (C) 2015 + * swift Project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of Swift Project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +#include "samplesconcurrent.h" +#include "blackmisc/algorithm.h" +#include +#include +#include +#include + +using namespace BlackMisc; + +namespace BlackMiscTest +{ + + int CSamplesConcurrent::samples(const QString &type, QTextStream &out, QTextStream &in) + { + Q_UNUSED(in); + Q_UNUSED(type); + + out << "Main thread id: " << QThread::currentThreadId() << endl; + CThreadOutput b1("b1"); + b1.start(); + CThreadOutput b2("b2"); + b2.start(); + CThreadOutput b3("b3"); + b3.start(); + QThread::msleep(10 * 1000); + b1.stop(); + b2.stop(); + b3.stop(); + QThread::msleep(1 * 1000); // allow to stop + + out << "Main thread id: " << QThread::currentThreadId() << endl; + CConcurrentOutput c1("c1"); + QtConcurrent::run(&c1, &CConcurrentOutput::doWork); + CConcurrentOutput c2("c2"); + QtConcurrent::run(&c2, &CConcurrentOutput::doWork); + CConcurrentOutput c3("c3"); + QtConcurrent::run(&c3, &CConcurrentOutput::doWork); + QThread::msleep(10 * 1000); + c1.stop(); + c2.stop(); + // stop 2, but then wait and see whats happening + out << "stopped c1, c2" << endl; + QThread::msleep(5 * 1000); + out << "stopped c3" << endl; + c3.stop(); + QThread::msleep(1 * 1000); // allow to stop + + return 0; + } + + CThreadOutput::CThreadOutput(const QString &name, QObject *parent) : + CContinuousWorker(parent, name) + { } + + void CThreadOutput::doWork() + { + QTextStream out(stdout); + while (m_run) + { + out << this->objectName() << " worker id: " << QThread::currentThreadId() << endl; + QThread::msleep(1000); + } + } + + void CThreadOutput::stop() + { + m_run = false; + } + + void CThreadOutput::initialize() + { + this->doWork(); + } + + CConcurrentOutput::CConcurrentOutput(const QString &name, QObject *parent) : + QObject(parent), m_name(name) + { } + + void CConcurrentOutput::stop() + { + m_run = false; + } + + void CConcurrentOutput::doWork() + { + QTextStream out(stdout); + while (m_run) + { + out << m_name << " worker id: " << QThread::currentThreadId() << endl; + QThread::msleep(1000); + } + } + +} // namespace diff --git a/samples/blackmisc/samplesconcurrent.h b/samples/blackmisc/samplesconcurrent.h new file mode 100644 index 000000000..97993a952 --- /dev/null +++ b/samples/blackmisc/samplesconcurrent.h @@ -0,0 +1,78 @@ +/* Copyright (C) 2015 + * swift Project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of Swift Project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +//! \file + +#ifndef BLACKMISCTEST_SAMPLESCONCURRENT_H +#define BLACKMISCTEST_SAMPLESCONCURRENT_H + +#include "blackmisc/worker.h" +#include +#include + +namespace BlackMiscTest +{ + + //! Samples for metadata + class CSamplesConcurrent + { + public: + //! Run the samples + static int samples(const QString &type, QTextStream &out, QTextStream &in); + }; + + //! Doing some work + class CThreadOutput : public BlackMisc::CContinuousWorker + { + Q_OBJECT + + public: + //! Constructor + CThreadOutput(const QString &name, QObject *parent = nullptr); + + //! Working task + void doWork(); + + //! Stop + void stop(); + + protected slots: + //! \copydoc CContinuousWorker::initialize + virtual void initialize() override; + + private: + std::atomic m_run { true }; + }; + + //! Doing some work + class CConcurrentOutput : public QObject + { + Q_OBJECT + + public: + //! Constructor + CConcurrentOutput(const QString &name, QObject *parent = nullptr); + + //! Stop + void stop(); + + public slots: + //! Working task + void doWork(); + + private: + std::atomic m_run { true }; + QString m_name; + }; + + + +} // namespace + +#endif diff --git a/src/blackmisc/worker.cpp b/src/blackmisc/worker.cpp index 3f026a8f4..04a16ab1f 100644 --- a/src/blackmisc/worker.cpp +++ b/src/blackmisc/worker.cpp @@ -46,8 +46,11 @@ namespace BlackMisc auto *thread = new CRegularThread(m_owner); - QString ownerName = m_owner->objectName().isEmpty() ? m_owner->metaObject()->className() : m_owner->objectName(); - thread->setObjectName(ownerName + ":" + m_name); + if (m_owner) + { + QString ownerName = m_owner->objectName().isEmpty() ? m_owner->metaObject()->className() : m_owner->objectName(); + thread->setObjectName(ownerName + ":" + m_name); + } setObjectName(m_name); moveToThread(thread); diff --git a/src/blackmisc/worker.h b/src/blackmisc/worker.h index 7d594c6ce..a4255fb45 100644 --- a/src/blackmisc/worker.h +++ b/src/blackmisc/worker.h @@ -249,7 +249,7 @@ namespace BlackMisc void ps_finish(); private: - QObject *m_owner; + QObject *m_owner = nullptr; QString m_name; }; diff --git a/src/swiftcore/main.cpp b/src/swiftcore/main.cpp index 5c5af95f9..ab815ef44 100644 --- a/src/swiftcore/main.cpp +++ b/src/swiftcore/main.cpp @@ -13,6 +13,7 @@ #include "blackcore/context_application.h" #include "blackcore/context_application_impl.h" #include "blackmisc/icons.h" +#include "blackmisc/worker.h" #include "blackmisc/networkutils.h" #include "blackmisc/blackmiscfreefunctions.h" #include "blackmisc/project.h" @@ -81,8 +82,12 @@ int main(int argc, char *argv[]) // tool to allow input indepent from event loop cout << "Will start server loop ... " << endl; - QFuture future = QtConcurrent::run(BlackMiscTest::Tool::serverLoop, coreRuntime); - Q_UNUSED(future); + BlackMisc::CWorker *worker = BlackMisc::CWorker::fromTask(coreRuntime, "BlackMiscTest::Tool::serverLoop", [coreRuntime]() + { + BlackMiscTest::Tool::serverLoop(coreRuntime); + }); + + Q_UNUSED(worker); cout << "Server event loop, pid: " << BlackMiscTest::Tool::getPid() << " Thread id: " << QThread::currentThreadId() << endl; // end