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. Problem with running timer in another thread
Qt 6.11 is out! See what's new in the release blog

Problem with running timer in another thread

Scheduled Pinned Locked Moved Solved General and Desktop
44 Posts 9 Posters 18.8k Views 3 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.
  • JonBJ Offline
    JonBJ Offline
    JonB
    wrote on last edited by
    #15

    As @jsulm says, reminder: objects created in thread constructor live in parent thread, objects created in thread run live in that thread.

    1 Reply Last reply
    0
    • SGaistS SGaist

      @Pl45m4 that's a bad idea: this will trigger a double deletion. One when the parent is deleted and the second when the object goes out of scope.

      Pl45m4P Offline
      Pl45m4P Offline
      Pl45m4
      wrote on last edited by Pl45m4
      #16

      @SGaist said in Problem with running timer in another thread:

      that's a bad idea: this will trigger a double deletion

      Oh my... that's why I initially thought of heap allocation and then using the parent-child architecture :D

      @jsulm said in Problem with running timer in another thread:

      Don't do this in the constructor, do it in the method which is actually executed in the other thread.

      But when creating the timer on the heap and as child of the containing class in the contructor... if you then move the ccDevice object, the timer (= child of ccDevice) is also moved, right?!

      @JoeCFD said in Problem with running timer in another thread:

      Allocating the timer on the heap or stack should not matter.

      So this doesn't matter in technical terms as the timer can/should be allocated on the stack, however when you want to use the parent-child relation to move the object to another thread, it does matter to avoid double deletion


      If debugging is the process of removing software bugs, then programming must be the process of putting them in.

      ~E. W. Dijkstra

      1 Reply Last reply
      0
      • Pl45m4P Pl45m4

        @JoeCFD

        I know :)
        Haven't checked the complete repository where and how everything is put together.

        But yeah,

        event_timer.setParent(this);
        

        might also work.

        D Offline
        D Offline
        Damian7546
        wrote on last edited by
        #17

        @Pl45m4 It doesn't work, still the same.

        1 Reply Last reply
        0
        • JoeCFDJ JoeCFD

          @Damian7546 Maybe try to add the following code into the func

              if ( QThread::currentThread() != thread() ) {
                  metaObject()->invokeMethod( this, "startTimer()", Qt::QueuedConnection );
                  return;
              }
          

          Make startTimer() to be a slot.

          D Offline
          D Offline
          Damian7546
          wrote on last edited by
          #18

          @JoeCFD said in Problem with running timer in another thread:

          @Damian7546 Maybe try to add the following code into the func

              if ( QThread::currentThread() != thread() ) {
                  metaObject()->invokeMethod( this, "startTimer()", Qt::QueuedConnection );
                  return;
              }
          

          Make startTimer() to be a slot.

          This one , still not working
          QMetaObject::invokeMethod: No such method qtcc::CctalkDevice::startTimer()()

          1 Reply Last reply
          0
          • hskoglundH Offline
            hskoglundH Offline
            hskoglund
            wrote on last edited by
            #19

            Hi, try without the parentheses, like this:
            ...
            metaObject()->invokeMethod( this, "startTimer", Qt::QueuedConnection );
            ...

            D 1 Reply Last reply
            1
            • hskoglundH hskoglund

              Hi, try without the parentheses, like this:
              ...
              metaObject()->invokeMethod( this, "startTimer", Qt::QueuedConnection );
              ...

              D Offline
              D Offline
              Damian7546
              wrote on last edited by Damian7546
              #20

              @hskoglund

              still the same QMetaObject::invokeMethod: No such method qtcc::CctalkDevice::startTimer()

              1 Reply Last reply
              0
              • D Offline
                D Offline
                Damian7546
                wrote on last edited by
                #21

                I thinking why we are talking about more than one thread? And why the error applies other thread? Since both CctalkDevice and MyCcTalkApp class are the same thread.... Only SerialWorker works in own thread which one is launched by CctalkLinkController .
                The polling timer is in CctalkDevice, so what is the problem ?

                JoeCFDJ 1 Reply Last reply
                0
                • D Damian7546

                  I thinking why we are talking about more than one thread? And why the error applies other thread? Since both CctalkDevice and MyCcTalkApp class are the same thread.... Only SerialWorker works in own thread which one is launched by CctalkLinkController .
                  The polling timer is in CctalkDevice, so what is the problem ?

                  JoeCFDJ Offline
                  JoeCFDJ Offline
                  JoeCFD
                  wrote on last edited by JoeCFD
                  #22

                  @Damian7546 print out thread ids on the screen in the constructor and in this function. Check out why they are different.

                  D 1 Reply Last reply
                  0
                  • hskoglundH Offline
                    hskoglundH Offline
                    hskoglund
                    wrote on last edited by
                    #23

                    Ah, I see in your cctalk_device.h file, startTimer() is declared under protected:
                    try moving it under slots: (like your function void timerIteration();)

                    1 Reply Last reply
                    0
                    • JoeCFDJ JoeCFD

                      @Damian7546 print out thread ids on the screen in the constructor and in this function. Check out why they are different.

                      D Offline
                      D Offline
                      Damian7546
                      wrote on last edited by Damian7546
                      #24

                      @hskoglund without changes.

                      @JoeCFD

                      QML debugging is enabled. Only use this in a safe environment.
                      ThreadID SerialWorker: 0x7cb34f9b27c0
                      ThreadID CctalkLinkController: 0x7cb34f9b27c0
                      ThreadID CctalkDevice: 0x7cb34f9b27c0
                      ThreadID MyCcTalkApp: 0x7cb34f9b27c0

                      LogMessgae: "* Coin acceptor configured device: /dev/ttyUSB0"
                      LogMessgae: "* Opening port "/dev/ttyUSB0"."
                      LogMessgae: "Requested device state change from ShutDown to: Initialized"
                      ThreadID in startTimer() 0x71df85200640
                      LogMessgae: "* Port "/dev/ttyUSB0" opened."
                      LogMessgae: "> ccTalk request: SimplePoll, address: 2, data: (empty)"
                      QMetaObject::invokeMethod: No such method qtcc::CctalkDevice::startTimer()
                      LogMessgae: "> Request: 020001feff"
                      LogMessgae: "< Full response: 020001feff01000200fd"
                      LogMessgae: "< ccTalk response from address 2, data: (empty)"
                      LogMessgae: "* Device is alive (answered to simple poll)"
                      QObject::startTimer: Timers cannot be started from another thread*

                      now I don't understand anything, why only the startTimer is on other thread?

                      JoeCFDJ 1 Reply Last reply
                      0
                      • D Damian7546

                        @hskoglund without changes.

                        @JoeCFD

                        QML debugging is enabled. Only use this in a safe environment.
                        ThreadID SerialWorker: 0x7cb34f9b27c0
                        ThreadID CctalkLinkController: 0x7cb34f9b27c0
                        ThreadID CctalkDevice: 0x7cb34f9b27c0
                        ThreadID MyCcTalkApp: 0x7cb34f9b27c0

                        LogMessgae: "* Coin acceptor configured device: /dev/ttyUSB0"
                        LogMessgae: "* Opening port "/dev/ttyUSB0"."
                        LogMessgae: "Requested device state change from ShutDown to: Initialized"
                        ThreadID in startTimer() 0x71df85200640
                        LogMessgae: "* Port "/dev/ttyUSB0" opened."
                        LogMessgae: "> ccTalk request: SimplePoll, address: 2, data: (empty)"
                        QMetaObject::invokeMethod: No such method qtcc::CctalkDevice::startTimer()
                        LogMessgae: "> Request: 020001feff"
                        LogMessgae: "< Full response: 020001feff01000200fd"
                        LogMessgae: "< ccTalk response from address 2, data: (empty)"
                        LogMessgae: "* Device is alive (answered to simple poll)"
                        QObject::startTimer: Timers cannot be started from another thread*

                        now I don't understand anything, why only the startTimer is on other thread?

                        JoeCFDJ Offline
                        JoeCFDJ Offline
                        JoeCFD
                        wrote on last edited by JoeCFD
                        #25

                        @Damian7546 move startTimer() to public slots:
                        public slots:
                        void startTimer();

                        if ( QThread::currentThread() != thread() ) {
                                metaObject()->invokeMethod( this, "startTimer", Qt::QueuedConnection );
                               return;
                        }
                        

                        If you have stop func for timer, you may need to do the same thing. The code above works in my app.

                        D 1 Reply Last reply
                        0
                        • JoeCFDJ JoeCFD

                          @Damian7546 move startTimer() to public slots:
                          public slots:
                          void startTimer();

                          if ( QThread::currentThread() != thread() ) {
                                  metaObject()->invokeMethod( this, "startTimer", Qt::QueuedConnection );
                                 return;
                          }
                          

                          If you have stop func for timer, you may need to do the same thing. The code above works in my app.

                          D Offline
                          D Offline
                          Damian7546
                          wrote on last edited by Damian7546
                          #26

                          @JoeCFD something is starting to work...

                          JoeCFDJ 1 Reply Last reply
                          0
                          • D Damian7546

                            @JoeCFD something is starting to work...

                            JoeCFDJ Offline
                            JoeCFDJ Offline
                            JoeCFD
                            wrote on last edited by
                            #27

                            @Damian7546 Have fun.

                            D 1 Reply Last reply
                            0
                            • JoeCFDJ JoeCFD

                              @Damian7546 Have fun.

                              D Offline
                              D Offline
                              Damian7546
                              wrote on last edited by Damian7546
                              #28

                              @hskoglund said in Problem with running timer in another thread:

                              Ah, I see in your cctalk_device.h file, startTimer() is declared under protected:
                              try moving it under slots: (like your function void timerIteration();)

                              Problem is more complicated then can I thought, probably not related with startTimer() function .
                              I totally remove calling startTimer() from my project and still have the same error :

                              QML debugging is enabled. Only use this in a safe environment.
                              ThreadID SerialWorker:   0x79e36d8867c0
                              ThreadID CctalkLinkController:   0x79e36d8867c0
                              ThreadID CctalkDevice:   0x79e36d8867c0
                              Using  "/home/developer/.config/CCtalkProj.ini"  as a user-specific settings file
                              ThreadID MyCcTalkApp:   0x79e36d8867c0
                              "* Coin acceptor configured device: /dev/ttyUSB0"
                              "* Opening port \"/dev/ttyUSB0\"."
                              "Requested device state change from ShutDown to: Initialized"
                              test test test
                              "* Port \"/dev/ttyUSB0\" opened."
                              "> ccTalk request: SimplePoll, address: 2, data: (empty)"
                              "> Request: 020001feff"
                              "< Full response: 020001feff01000200fd"
                              "< ccTalk response from address 2, data: (empty)"
                              "* Device is alive (answered to simple poll)"
                              QObject::startTimer: Timers cannot be started from another thread
                              

                              Below I publish code wihich I try run:
                              [https://github.com/ienecode/cctalk.git](link url)

                              1 Reply Last reply
                              0
                              • D Offline
                                D Offline
                                Damian7546
                                wrote on last edited by
                                #29

                                @JoeCFD @JoeCFD code analysis should be do from the creating object - MyCcTalkApp, where are created
                                Coin acceptor communicator - qtcc::Coin AcceptorDevice coin acceptor _;
                                Analyzing further do you see any problems ?

                                1 Reply Last reply
                                0
                                • J.HilkJ Offline
                                  J.HilkJ Offline
                                  J.Hilk
                                  Moderators
                                  wrote on last edited by
                                  #30

                                  Still the same problem as originally.

                                  your 'serial_port_' is not moved with move ToThread QSerialPort uses internally QTimer thats why you see the message.


                                  Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                                  Q: What's that?
                                  A: It's blue light.
                                  Q: What does it do?
                                  A: It turns blue.

                                  1 Reply Last reply
                                  2
                                  • D Offline
                                    D Offline
                                    Damian7546
                                    wrote on last edited by
                                    #31

                                    @J-Hilk So, how can I fix this code ? Can you give me tips ?

                                    J.HilkJ 1 Reply Last reply
                                    0
                                    • Christian EhrlicherC Offline
                                      Christian EhrlicherC Offline
                                      Christian Ehrlicher
                                      Lifetime Qt Champion
                                      wrote on last edited by
                                      #32

                                      Pass the correct parent to your timer.

                                      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                                      Visit the Qt Academy at https://academy.qt.io/catalog

                                      1 Reply Last reply
                                      0
                                      • D Damian7546

                                        @J-Hilk So, how can I fix this code ? Can you give me tips ?

                                        J.HilkJ Offline
                                        J.HilkJ Offline
                                        J.Hilk
                                        Moderators
                                        wrote on last edited by
                                        #33

                                        @Damian7546

                                        1. Fix your constructor of your QObject based worker: More of a principal matter in this case
                                        class SerialWorker : public QObject {
                                        	Q_OBJECT
                                        	public:
                                        
                                        		/// Constructor
                                        		SerialWorker();
                                        ...->...
                                        class SerialWorker : public QObject {
                                        	Q_OBJECT
                                        	public:
                                        
                                        		/// Constructor
                                        		explicit SerialWorker(QObbject *parent = nullptr);
                                        .....
                                        SerialWorker::SerialWorker()
                                        {
                                        ...->...
                                        SerialWorker::SerialWorker(QObject*parent) : QObject(parent)
                                        {
                                        
                                        1. Drop the scoped pointer, you're trying to be fancy when there's no need for it and it's causing trouble
                                        QScopedPointer<QSerialPort> serial_port_; 
                                        ...->
                                        QSerialPort * const serial_port_; //Raw dogging the serial port, hell ya 
                                        
                                        1. Init the QSerialport correctly:
                                        SerialWorker::SerialWorker(QObject*parent) : QObject(parent), serial_port_{new QSerialPort(this)}
                                        {
                                        

                                        Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                                        Q: What's that?
                                        A: It's blue light.
                                        Q: What does it do?
                                        A: It turns blue.

                                        Pl45m4P 1 Reply Last reply
                                        2
                                        • J.HilkJ J.Hilk

                                          @Damian7546

                                          1. Fix your constructor of your QObject based worker: More of a principal matter in this case
                                          class SerialWorker : public QObject {
                                          	Q_OBJECT
                                          	public:
                                          
                                          		/// Constructor
                                          		SerialWorker();
                                          ...->...
                                          class SerialWorker : public QObject {
                                          	Q_OBJECT
                                          	public:
                                          
                                          		/// Constructor
                                          		explicit SerialWorker(QObbject *parent = nullptr);
                                          .....
                                          SerialWorker::SerialWorker()
                                          {
                                          ...->...
                                          SerialWorker::SerialWorker(QObject*parent) : QObject(parent)
                                          {
                                          
                                          1. Drop the scoped pointer, you're trying to be fancy when there's no need for it and it's causing trouble
                                          QScopedPointer<QSerialPort> serial_port_; 
                                          ...->
                                          QSerialPort * const serial_port_; //Raw dogging the serial port, hell ya 
                                          
                                          1. Init the QSerialport correctly:
                                          SerialWorker::SerialWorker(QObject*parent) : QObject(parent), serial_port_{new QSerialPort(this)}
                                          {
                                          
                                          Pl45m4P Offline
                                          Pl45m4P Offline
                                          Pl45m4
                                          wrote on last edited by
                                          #34

                                          @J-Hilk said in Problem with running timer in another thread:

                                          Fix your constructor of your QObject based worker: More of a principal matter in this case

                                          Drop the scoped pointer, you're trying to be fancy when there's no need for it and it's causing trouble

                                          Init the QSerialport correctly:

                                          TBH these things are also "weird" / designed badly in the original repository, @Damian7546 just copied/forked this structure.
                                          I'm wondering if any of the original stuff actually works... from looking at it I would say it also has many issues.
                                          Usually just including the class inQObject's parent-child structure and therefore moving the thread affinity with the parent would fix this. That's what I wrote/thought earlier, but it seems that this is not so easy to do due to the way the whole thing is designed.

                                          QSerialPort * const serial_port_; //Raw dogging the serial port, hell ya 
                                          

                                          LMAO :D


                                          If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                                          ~E. W. Dijkstra

                                          1 Reply Last reply
                                          1

                                          • Login

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