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. Initialization in a new thread.
Forum Updated to NodeBB v4.3 + New Features

Initialization in a new thread.

Scheduled Pinned Locked Moved General and Desktop
9 Posts 3 Posters 5.1k Views 1 Watching
  • 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.
  • H Offline
    H Offline
    Hibou
    wrote on last edited by
    #1

    I am doing threading right, and was wondering how to declare heap variables in my new thread.
    Now the way I do it is, I connect two slots "slot_1" and "slot_2" to execute when the new thread starts (connecting them in that order).
    In slot_1, I perform initialization and declare my heap variables.
    In slot_2, I do my work.

    My question: Am I assured that all variables will come into existence by the time slot_2 is invoked?
    (I know... silly lab rat! Do the initialization first, in the same slot, and then proceed to doing the work! No need for 2 slots!... Well, yes, I need it. My slot_2 is invoked by another signal, repeatedly, so I can't initialize anything in it.
    Thanks

    1 Reply Last reply
    0
    • JKSHJ Offline
      JKSHJ Offline
      JKSH
      Moderators
      wrote on last edited by
      #2

      Hi, and welcome to the Qt Dev Net!

      Can you show us some code on how you have set up your thread? What class does "slot_1" and "slot_2" belong to?

      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

      1 Reply Last reply
      0
      • H Offline
        H Offline
        Hibou
        wrote on last edited by
        #3

        Thank you.
        Tying the question above to my example code below, slot_1 is "doInit", and slot_2 is "process". You will see that both slots belong to the "Dataserver".
        Here is my main:
        @int main(int argc, char *argv[])
        {
        QApplication a(argc, argv);

        MainWindow w;
        w.show();
        
        // create the dataserver thread:
        QThread * dsThread = new QThread;
        // create the dataserver worker object:
        Dataserver dataserver;
        
        dataserver.doConnections(*dsThread, &w);
        
        // move the worker object onto the new thread:
        dataserver.moveToThread(dsThread);
        
        dsThread->start();
        return a.exec();
        

        }@

        Now the Dataserver class header file:

        @class Dataserver : public QObject
        {
        Q_OBJECT
        public:
        explicit Dataserver(QObject *parent = 0);
        void doConnections(QThread &cThread, MainWindow *);
        ~Dataserver();

        signals:
        void finished();

        public slots:
        void process();
        void doInit();

        private:
        StatusCollector * statusCollector; // token pointer to heap object
        };@

        and the Dataserver class .cpp file:

        @void Dataserver::doConnections(QThread &cThread, MainWindow *win)
        {
        // When the thread starts, do one time initialization:
        connect(&cThread, SIGNAL(started()), this, SLOT(doInit()));
        // When the thread starts, run:
        connect(&cThread, SIGNAL(started()), this, SLOT(process()));
        // On closing down, wait for thread to complete
        connect(&cThread, SIGNAL(finished()), &cThread, SLOT(deleteLater()));
        }

        void Dataserver::doInit()
        {
        // create heap variables
        statusCollector = new StatusCollector(this);
        // and more...
        }

        void Dataserver::process()
        {
        // This slot is started on thread start, and waits on a precise real-time
        // clock interrupt; When the real-time interrupt happens, this wakes up and
        // executes a number of functions, and returns to waiting on the
        // real time clock interrupt.
        }
        @
        To recap, on the start of dsThread, two slots are invoked: the "doInit" slot and the "process" slot, both in the worker dataserver object.
        So my question is, will "doInit" be done (i.e. will the statusCollector come into existence) by the time my slot "process" is invoked?

        1 Reply Last reply
        0
        • X Offline
          X Offline
          Xander84
          wrote on last edited by
          #4

          slots should be invoked in the same order they have been defined, but the question here is do you really need to connect 2 different slots to the same signal? :D

          you could call the doInit() function once in your process slot (I know you said that is not possible, but why not?) or you could use an intermediate slot to call both slots form there, or call the process() slot from the doInit() slot, that is all the same result to me, is it not?

          Anyway it seems a little weird how you use the QThread with the Dataserver is not derived from QThread or some easier solution, just wondering :)

          1 Reply Last reply
          0
          • H Offline
            H Offline
            Hibou
            wrote on last edited by
            #5

            I agree, the simpler solution is a function call to "doInit" from the "process" slot, once.
            About the last paragraph and the qthread, I have read that subclassing qthreads is not the correct way to do it; So I instantiate a worker object (dataserver) and hoist it onto the new thread, with moveToThread.
            But I always wondered how to instantiate new heap parameters in objects belonging to the new thread, since you shouldn't invoke the objects' constructors form your main thread...

            1 Reply Last reply
            0
            • JKSHJ Offline
              JKSHJ Offline
              JKSH
              Moderators
              wrote on last edited by
              #6

              [quote author="Xander84" date="1396981794"]slots should be invoked in the same order they have been defined[/quote]Correct. From the "Signals and Slots documentation":http://qt-project.org/doc/qt-5/signalsandslots.html:

              "If several slots are connected to one signal, the slots will be executed one after the other, in the order they have been connected, when the signal is emitted."

              [quote author="Hibou" date="1396982720"]I agree, the simpler solution is a function call to "doInit" from the "process" slot, once.[/quote]Your original solution is fine.

              Other thoughts: Do you need to run process() when the thread starts? Could you just run doInit() when the thread starts, and let your other signal trigger process()?

              [quote author="Xander84" date="1396981794"]Anyway it seems a little weird how you use the QThread with the Dataserver is not derived from QThread or some easier solution, just wondering :)[/quote]No, deriving from QThread is not a good solution here. Hibou explained in his original post that his process() slot will be invoked repeatedly by another signal. You should use a worker object for that.

              [quote]About the last paragraph and the qthread, I have read that subclassing qthreads is not the correct way to do it; So I instantiate a worker object (dataserver) and hoist it onto the new thread, with moveToThread.[/quote]Subclassing QThread and using a worker object are two different ways to use QThread -- you should choose the solution based on your use case. "Multithreading Technologies in Qt":http://qt-project.org/doc/qt-5/threads-technologies.html and the "QThread documentation":http://qt-project.org/doc/qt-5/qthread.html explain how to choose.

              In your case, creating a worker object was the correct choice, because you are using signals to trigger functions (slots) in your new thread.

              [quote]But I always wondered how to instantiate new heap parameters in objects belonging to the new thread, since you shouldn’t invoke the objects’ constructors form your main thread…[/quote]It depends on the nature of your heap objects. If they can be moved to another thread, then just allocate them in your Dataserver constructor, and make Dataserver their parent. When you move Dataserver to the new thread, its children will be moved too. See "QObject|Thread Affinity":http://qt-project.org/doc/qt-5/QObject.html#thread-affinity for details.

              What kind of objects do you create in doInit()?

              Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

              1 Reply Last reply
              0
              • H Offline
                H Offline
                Hibou
                wrote on last edited by
                #7

                Thank you JKSH. Indeed, I could simply forgo the doInit() slot or function, if the new objects declared in the Dataserver constructor are children of the Dataserver object. The objects I create in doInit() are several, for instance an object to collect status from several TCP sockets, some objects to collect status from serial ports, etc. I greatly simplified the list and only kept one, but it could be long.
                As for this question:

                bq. JKSH asked: "Other thoughts: Do you need to run process() when the thread starts? Could you just run doInit() when the thread starts, and let your other signal trigger process()?"

                Yes, I believe I do. I am using a scheduler developed by another group, and for them to call my function repeatedly, at a very precise time, is to set it up when the thread starts. Then I wait for their signal. This function, by the way, is not "process" but yet another function to do the cyclic execution. So "process" simply sets things up, and coordinates with the scheduler.
                Convoluted, but this way I leave the work of integrating the Timing IRIG-B board and interrupt vectoring to the low-level guys, and I stay at a fairly high level.

                1 Reply Last reply
                0
                • JKSHJ Offline
                  JKSHJ Offline
                  JKSH
                  Moderators
                  wrote on last edited by
                  #8

                  Hmm... I'm not sure if QTcpSocket and QSerialPort can be moved after construction or not. I'll have a look when I get home.

                  Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                  1 Reply Last reply
                  0
                  • H Offline
                    H Offline
                    Hibou
                    wrote on last edited by
                    #9

                    Oh, I am not actually creating QTcpSocket's or QSerialPort's in this thread. I am sorry, I should have been clearer. They are in their own thread, and I interface to them via shared memory. I know there is no real need to place sockets in a different thread, but I do not want to process any incoming signals in my Dataserver thread (at least, after it gets going). The I/O thread, as I call it, will do all the asynchronous message receiving with slots.
                    Thanks for bringing this up.

                    1 Reply Last reply
                    0

                    • Login

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