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 19.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.
  • 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 Online
      hskoglundH Online
      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 Online
                        Christian EhrlicherC Online
                        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
                            • D Offline
                              D Offline
                              Damian7546
                              wrote on last edited by
                              #35

                              @J-Hilk After changes proposed by you , the logs are this:

                              "* Coin acceptor configured device: /dev/ttyUSB0"
                              "* Opening port \"/dev/ttyUSB0\"."
                              "Requested device state change from ShutDown to: Initialized"
                              "* Port \"/dev/ttyUSB0\" opened."
                              "> ccTalk request: SimplePoll, address: 2, data: (empty)"
                              "Starting poll timer."
                              "> Request: 020001feff"
                              "Polling......"
                              "< 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
                              "Polling......"
                              "Polling......"
                              "Polling......"
                              "- The last message was repeated 40 times total"
                              "- The last message was repeated 80 times total"
                              "- The last message was repeated 120 times total"
                              "- The last message was repeated 160 times total"
                              
                              JonBJ Pl45m4P 2 Replies Last reply
                              0
                              • D Damian7546

                                @J-Hilk After changes proposed by you , the logs are this:

                                "* Coin acceptor configured device: /dev/ttyUSB0"
                                "* Opening port \"/dev/ttyUSB0\"."
                                "Requested device state change from ShutDown to: Initialized"
                                "* Port \"/dev/ttyUSB0\" opened."
                                "> ccTalk request: SimplePoll, address: 2, data: (empty)"
                                "Starting poll timer."
                                "> Request: 020001feff"
                                "Polling......"
                                "< 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
                                "Polling......"
                                "Polling......"
                                "Polling......"
                                "- The last message was repeated 40 times total"
                                "- The last message was repeated 80 times total"
                                "- The last message was repeated 120 times total"
                                "- The last message was repeated 160 times total"
                                
                                JonBJ Offline
                                JonBJ Offline
                                JonB
                                wrote on last edited by JonB
                                #36

                                @Damian7546
                                At this point I doubt that anyone can reliably know what exactly your code reads. You clearly still have a thread issue.

                                I am unsure: have you identified where the startTimer() call is issued from in code?

                                1 Reply Last reply
                                0
                                • D Damian7546

                                  @J-Hilk After changes proposed by you , the logs are this:

                                  "* Coin acceptor configured device: /dev/ttyUSB0"
                                  "* Opening port \"/dev/ttyUSB0\"."
                                  "Requested device state change from ShutDown to: Initialized"
                                  "* Port \"/dev/ttyUSB0\" opened."
                                  "> ccTalk request: SimplePoll, address: 2, data: (empty)"
                                  "Starting poll timer."
                                  "> Request: 020001feff"
                                  "Polling......"
                                  "< 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
                                  "Polling......"
                                  "Polling......"
                                  "Polling......"
                                  "- The last message was repeated 40 times total"
                                  "- The last message was repeated 80 times total"
                                  "- The last message was repeated 120 times total"
                                  "- The last message was repeated 160 times total"
                                  
                                  Pl45m4P Offline
                                  Pl45m4P Offline
                                  Pl45m4
                                  wrote on last edited by
                                  #37

                                  @Damian7546

                                  Since you probably used the code from the original GitHub repo without modifying it, you should reach out to the owner of the repo via GitHub issues.
                                  Maybe he can identify the problem as a whole faster than a bunch of people in the forum here, who have to dive into the project first and dig through the logic to understand how everything is put together.
                                  As @J-Hilk mentioned above, there are a couple of things that could have been done cleaner...
                                  (creating QObject derived worker without actually calling the QObject base implementation... etc...)


                                  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
                                  • D Offline
                                    D Offline
                                    Damian7546
                                    wrote on last edited by
                                    #38

                                    @JonB
                                    My opinion it call only once, in the CctalkDevice::requestSwitchDeviceState (cctalk_device.cpp) , when the device goes to Initialized.
                                    241 linie: https://github.com/ienecode/cctalk/blob/main/cctalk/cctalk_device.cpp

                                    @Pl45m4
                                    I contacted the author, and he tells me that this code was developed for a project that was stopped before there was a chance to properly test the code,
                                    so this is the state it was left in.

                                    I interesed in this code, because I think that the structure of this code for SERIAL communication seems very reasonable and developmental to me.

                                    So I would be really grateful if anyone of forumers could be help me run this code , especially to run cyclic polling , in way is realized in this code.

                                    1 Reply Last reply
                                    0
                                    • Christian EhrlicherC Online
                                      Christian EhrlicherC Online
                                      Christian Ehrlicher
                                      Lifetime Qt Champion
                                      wrote on last edited by
                                      #39

                                      I don't see a reason to use threads for simple serial communication with QSerialPort at all. It just complicates things, esp. for people without proper knowledge about threads. Don't use it - simply use QSerialPort and proper signals & slots.

                                      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
                                      2
                                      • D Offline
                                        D Offline
                                        Damian7546
                                        wrote on last edited by Damian7546
                                        #40

                                        @Christian-Ehrlicher I expected such answers: "simply use QSerialPort and proper signals & slots." . I have project realized in this way.
                                        But as part of learning (main goal of the project) programming and uing threads I would like to use threads this time to serial communication, and run example considered in this topic.

                                        JonBJ Pl45m4P Christian EhrlicherC 3 Replies Last reply
                                        0
                                        • D Damian7546

                                          @Christian-Ehrlicher I expected such answers: "simply use QSerialPort and proper signals & slots." . I have project realized in this way.
                                          But as part of learning (main goal of the project) programming and uing threads I would like to use threads this time to serial communication, and run example considered in this topic.

                                          JonBJ Offline
                                          JonBJ Offline
                                          JonB
                                          wrote on last edited by JonB
                                          #41

                                          @Damian7546
                                          Then by choosing to use threads where they are probably not needed you (or the original author) have ended up with a problem using threads, possibly because the original code was not well written for threads. Which tells you a lot... ! Just saying.

                                          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