Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QThread correct usage
Forum Update on Monday, May 27th 2025

QThread correct usage

Scheduled Pinned Locked Moved Unsolved General and Desktop
qthreadmultithreadc++
5 Posts 2 Posters 2.3k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    shav
    wrote on 20 Jul 2018, 09:53 last edited by
    #1

    Hi everyone!

    I have a images gallery application. All images I'm loading in QThread. In QtCreator all works fine (Release and Debug mode). But if I try to load my app just click on MyApplication.app I can't get images list only at first time. When I try to refresh the list I'm receiving error:

    2018-07-20 12:48:36.834 ShavSample[15543:506104] Persistent UI failed to open file file:///Users/andrewsh/Library/Saved%20Application%20State/com.consultica.ShavSample.savedState/window_1.data: Too many open files (24)
    QThreadPipe: Unable to create pipe: Too many open files
    QEventDispatcherUNIXPrivate(): Can not continue without a thread pipe
    Abort trap: 6
    

    I'm using Qt 5.11 on macOS 10.13.6.
    Create a worker:

    ShavGetImagesInfoWorker* worker = new ShavGetImagesInfoWorker(urls, callback);
    if(!ShavTaskManager::isObjectCreated()) {
        ShavTaskManager::initManager();
    }
    ShavTaskManager::shared()->startWork(worker);
    

    Start thread:

    if(worker) {
        m_tasks.append(worker);
        QThread* newThread = new QThread();
        connect(newThread, &QThread::started, worker, &ShavThreadWorker::run);
        connect(worker, &ShavThreadWorker::finished, this, &ShavTaskManager::onFinished);
        connect(worker, &ShavThreadWorker::finished, newThread, &QThread::quit);
        connect(newThread, &QThread::finished, newThread, &QObject::deleteLater);
        worker->moveToThread(newThread);
        newThread->start(static_cast<QThread::Priority>(priority));
    }
    

    All worker is a subclass from class:

    class ShavThreadWorker : public QObject
    {
            Q_OBJECT
        private:
            ShavTaskResult* m_result;
            ShavTaskResult* m_progress;
            QMutex m_mutex;
        protected:
            virtual QObject* doTaskAction();
            void updateProgress(QVariant value, QVariant total, QVariant userData = QVariant());
        public:
            explicit ShavThreadWorker(QJSValue callback, QObject *parent = nullptr);
            explicit ShavThreadWorker(QJSValue callback, QJSValue progress, QObject *parent = nullptr);
            ~ShavThreadWorker();
        signals:
            void finished();
        private slots:
            inline void onFinishedResult() {
                emit finished();
            }
        public slots:
            void run();
            inline void stop() {
                this->thread()->requestInterruption();
            }
     };
    

    and implementation of calls:

    QObject *ShavThreadWorker::doTaskAction() {
        return nullptr;
    }
    
    void ShavThreadWorker::updateProgress(QVariant value, QVariant total, QVariant userData) {
        if(userData.isNull()) {
            QMetaObject::invokeMethod(m_progress, "updateProgress", Qt::QueuedConnection,
                                      Q_ARG(QVariant, value), Q_ARG(QVariant, total));  //Main thread
        } else {
            QMetaObject::invokeMethod(m_progress, "updateProgress", Qt::QueuedConnection,
                                      Q_ARG(QVariant, value), Q_ARG(QVariant, total), Q_ARG(QVariant, userData));  //Main thread
        }
    }
    
    
    ShavThreadWorker::ShavThreadWorker(QJSValue callback, QObject *parent) : QObject(parent) {
        static int index = 0;
        setObjectName(QString("%1_%2").arg(metaObject()->className()).arg(index));
        index += 1;
    
        m_result = new ShavTaskResult(callback);
        connect(m_result, SIGNAL(finished()), SLOT(onFinishedResult()));
        m_progress = nullptr;
    }
    
    ShavThreadWorker::ShavThreadWorker(QJSValue callback, QJSValue progress, QObject *parent) : QObject(parent) {
        static int index = 0;
        setObjectName(QString("%1_%2").arg(metaObject()->className()).arg(index));
        index += 1;
    
        m_result = new ShavTaskResult(callback);
        connect(m_result, SIGNAL(finished()), SLOT(onFinishedResult()));
        m_progress = new ShavTaskResult(progress);
    }
    
    ShavThreadWorker::~ShavThreadWorker() {
    #ifdef QT_DEBUG
        qDebug()<<metaObject()->className()<<"was released!";
    #endif
    }
    
    void ShavThreadWorker::run() {
        m_mutex.lock();
        QObject* res = doTaskAction();
        if(m_result != nullptr) {
            res->moveToThread(qApp->thread());
            QMetaObject::invokeMethod(m_result, "sendResult", Qt::QueuedConnection, Q_ARG(QObject*, res));  //Main thread
        } else {
            onFinishedResult();
        }
        m_mutex.unlock();
    }
    

    Mac OS and iOS Developer

    1 Reply Last reply
    0
    • V Offline
      V Offline
      VRonin
      wrote on 20 Jul 2018, 10:07 last edited by
      #2

      Having too many threads makes performance worse than having just 1.

      Rather than having a new thread having time you should distribute the work among QThread::IdealThreadCount threads

      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
      ~Napoleon Bonaparte

      On a crusade to banish setIndexWidget() from the holy land of Qt

      1 Reply Last reply
      3
      • S Offline
        S Offline
        shav
        wrote on 20 Jul 2018, 11:42 last edited by shav
        #3

        Thanks for the reply! Could you share links to the example how to use QThread::IdealThreadCount? In Qt docs I can't find examples for this.

        P.S. Also I try to use QThreadPool for call task But this also not working :(

        Mac OS and iOS Developer

        1 Reply Last reply
        0
        • V Offline
          V Offline
          VRonin
          wrote on 20 Jul 2018, 12:21 last edited by
          #4

          The closest i have to an example is https://github.com/VSRonin/ChatExample/blob/master/QtSimpleChatServerThreaded/chatserver.cpp

          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
          ~Napoleon Bonaparte

          On a crusade to banish setIndexWidget() from the holy land of Qt

          1 Reply Last reply
          4
          • S Offline
            S Offline
            shav
            wrote on 20 Jul 2018, 18:40 last edited by
            #5

            Thanks, I will check!

            Mac OS and iOS Developer

            1 Reply Last reply
            0

            3/5

            20 Jul 2018, 11:42

            • Login

            • Login or register to search.
            3 out of 5
            • First post
              3/5
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved