How to use QThreadStorage class?



  • hi, I saw the QThreadStorage in manual. I don't know how to use it. I didn't find anything about QThreadStorage in internet.

    the manual give me the code

      QThreadStorage<QCache<QString, SomeClass> > caches; /// is caches a member of subclass QThread? do i must use some class ? 
    
      void cacheObject(const QString &key, SomeClass *object)
      {
          caches.localData().insert(key, object);
      }
    
      void removeFromCache(const QString &key)
      {
          if (!caches.hasLocalData())
              return;
    
          caches.localData().remove(key);
      }
    
    1. Can you show me a demo about it?
    2. Can you tell me when i should to use the QThreadStorage in thread?
    3. What are the advantages use the QThreadStorages?

    I tried some way, not work.

    #ifndef SUBQTHREAD_H
    #define SUBQTHREAD_H
    
    #include <QThread>
    
    #include <QPoint>
    #include <QCache>
    #include <QThreadStorage>
    
    /** I tried struct, but failed at first. so, i used the QPoint to tried, also failed. */
    struct Data{
        bool bFlag = false;
        int  num = 0;
        double dVal = 0.0;
        float  fVal = 0.0;
    };
    
    class SubQThread : public QThread
    {
        Q_OBJECT
    public:
        explicit SubQThread(QObject *parent = 0);
        //explicit SubQThread(Data &dt,QObject *parent = 0);
        explicit SubQThread(QPoint *pt,QObject *parent = 0);
    
    private:
        void run() Q_DECL_OVERRIDE;
    
    private:
        //QThreadStorage<QCache<int,Data>> _thStorage;
        QThreadStorage<QCache<int,QPoint>> _thStorage;
    };
    
    #endif // SUBQTHREAD_H
    
    
    #include "subqthread.h"
    
    #include <QThread>
    #include <QDebug>
    
    SubQThread::SubQThread(QObject *parent):QThread(parent)
    {
    }
    /*
    SubQThread::SubQThread(Data &dt, QObject *parent):QThread(parent)
    {
        //_thStorage.localData().insert(1,&dt);
    }
    */
    SubQThread::SubQThread(QPoint *pt, QObject *parent):QThread(parent)
    {
        _thStorage.localData().insert(1,pt);
    }
    
    void SubQThread::run()
    {
        qDebug() << "SubThread Id" << QThread::currentThreadId() <<
                    "has the Data" << _thStorage.hasLocalData();
    }
    
    
    #include <QCoreApplication>
    #include "subqthread.h"
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        SubQThread th;
        th.start();
    
        /*Data dt;
        SubQThread th2(dt);
        th2.start();*/
    
        QPoint pt;
        SubQThread th3(&pt);
        th3.start();
    
        th.wait();
        //th2.wait();
        th3.wait();
    
        return a.exec();
    }
    

  • Lifetime Qt Champion

    Hi,

    Except that you are mixing pointer to QPoint and QPoint object which is wrong.

    1. Look in Qt's sources
    2. When you need to store and retrieve data on a per thread basis
    3. You don't need to do the data/thread matching yourself both when storing and retrieving data.


  • @SGaist Thank u, i get it. but, i have some trouble.

    like the code

    SubQThread.h

    class SubQThread : public QThread
    {
        Q_OBJECT
    public:
        explicit SubQThread(QPoint *pt,QObject *parent = 0);
    
    private:
        void run() Q_DECL_OVERRIDE;
    
    private:
        QThreadStorage<QPoint*> _thStorage;
    };
    

    SubQThread.cpp

    #include "subqthread.h"
    
    #include <QThread>
    #include <QDebug>
    
    SubQThread::SubQThread(QPoint *pt, QObject *parent):QThread(parent)
    {
        _thStorage.setLocalData(pt);
        qDebug() << "has the Data:" << _thStorage.hasLocalData(); ///here is true
    }
    
    void SubQThread::run()
    {
        qDebug() << "SubThread Id" << QThread::currentThreadId() <<
                    "has the Data" << _thStorage.hasLocalData(); /// here is false
    }
    

    main.cpp

    #include <QCoreApplication>
    #include "subqthread.h"
    
    /** QtCore */
    #include <QDebug>
    #include <QThread>
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        qDebug() << "Main Id:" << QThread::currentThreadId();
    
        QPoint* pt = new QPoint;
        SubQThread th3(pt);
        th3.start();
    
        return a.exec();
    }
    

    Why done QThreadStorage qDebug false in run function?


  • Lifetime Qt Champion

    Because the constructor runs in the thread of the object that creates your SubQThread instance while the run method will be called in the thread that is handled by QThread.



  • @SGaist Can you help me ? Show me some code about use the QThreadStorage in thread. just a little demo is OK. i tried failed. I only want to write a blog about how to use the QThreadStorage. but, i didn't find any demo about QThreadStorage.


  • Moderators

    @joeQ As @SGaist said: you're storing in QThreadStorage in the constructor of SubQThread. This constructor is executed in DIFFERENT thread than run() method - that's why you get false. QThreadStorage stores thread local data - data stored in one thread is not available in another. Move this line

    _thStorage.setLocalData(pt);
    

    to run() then it should print true.
    There is already a demo in documentation: http://doc.qt.io/qt-5.8/qthreadstorage.html



  • @jsulm @SGaist Thank u, I get what i want. i am sorry to bother you.


  • Moderators

    @joeQ Well, the forum is there to ask questions :-)


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.