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. Timers cannot be ####### from another thread
Forum Updated to NodeBB v4.3 + New Features

Timers cannot be ####### from another thread

Scheduled Pinned Locked Moved Unsolved General and Desktop
27 Posts 4 Posters 4.8k Views 2 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.
  • SPlattenS Offline
    SPlattenS Offline
    SPlatten
    wrote on last edited by
    #1

    I log all errors to a file during my applications life, I am seeing quite a few:

    QObject::killTimer: Timers cannot be stopped from another thread
    QObject::startTimer: Timers cannot be started from another thread
    

    In the output, I've tried to establish what is causing this because everywhere I use a timer I use a signal when it's done with and the slot is the place where the timer is stopped, same goes for starting so I'm scratching my head a to why this is still occurring.

    Can anyone help?

    Kind Regards,
    Sy

    eyllanescE 1 Reply Last reply
    0
    • SPlattenS SPlatten

      I log all errors to a file during my applications life, I am seeing quite a few:

      QObject::killTimer: Timers cannot be stopped from another thread
      QObject::startTimer: Timers cannot be started from another thread
      

      In the output, I've tried to establish what is causing this because everywhere I use a timer I use a signal when it's done with and the slot is the place where the timer is stopped, same goes for starting so I'm scratching my head a to why this is still occurring.

      Can anyone help?

      eyllanescE Offline
      eyllanescE Offline
      eyllanesc
      wrote on last edited by
      #2

      @SPlatten This warning indicates that you are using some QObject in a thread it does not belong to, and it indicates it because the QObjects are not thread-safe

      If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

      SPlattenS 1 Reply Last reply
      1
      • eyllanescE eyllanesc

        @SPlatten This warning indicates that you are using some QObject in a thread it does not belong to, and it indicates it because the QObjects are not thread-safe

        SPlattenS Offline
        SPlattenS Offline
        SPlatten
        wrote on last edited by
        #3

        @eyllanesc , thank you, I thought specifically it was telling me that the timers had been stopped and started in a thread, but I cannot see this?

        Kind Regards,
        Sy

        eyllanescE 1 Reply Last reply
        0
        • SPlattenS SPlatten

          @eyllanesc , thank you, I thought specifically it was telling me that the timers had been stopped and started in a thread, but I cannot see this?

          eyllanescE Offline
          eyllanescE Offline
          eyllanesc
          wrote on last edited by
          #4

          @SPlatten Internals of QObjects(and eventloop) use timers, and that is what is happening. That is why QObjects cannot be thread-safe: they handle many, many elements internally

          If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

          SPlattenS 1 Reply Last reply
          0
          • eyllanescE eyllanesc

            @SPlatten Internals of QObjects(and eventloop) use timers, and that is what is happening. That is why QObjects cannot be thread-safe: they handle many, many elements internally

            SPlattenS Offline
            SPlattenS Offline
            SPlatten
            wrote on last edited by
            #5

            @eyllanesc Sounds like a mine field...how can I trace where the issue is or what the cause is?

            Kind Regards,
            Sy

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #6

              Hi,

              Where do you have that timer ?
              What object owns it ?
              When do you create that timer ?
              Are you using moveToThread with the object where you have that timer ?

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              SPlattenS 1 Reply Last reply
              0
              • SGaistS SGaist

                Hi,

                Where do you have that timer ?
                What object owns it ?
                When do you create that timer ?
                Are you using moveToThread with the object where you have that timer ?

                SPlattenS Offline
                SPlattenS Offline
                SPlatten
                wrote on last edited by
                #7

                @SGaist , In the application that is reporting the problems:

                There is only one instance of QTimer defined in the class clsMsgTrkr, this is created and started in the constructor:

                    mptmrMonitor = new QTimer(this);
                    QObject::connect(mptmrMonitor, &QTimer::timeout, this, &clsMsgTrkr::onTimeout);
                    mptmrMonitor->start(clsMsgTrkr::mscuint16AckTimeout);
                

                The only other reference to this timer is in the slot onCleanup:

                void clsMsgTrkr::onCleanup() {
                    if ( mptmrMonitor != nullptr ) {
                        if ( mptmrMonitor->isActive() == true ) {
                            mptmrMonitor->stop();
                        }
                        delete mptmrMonitor;
                        mptmrMonitor = nullptr;
                }
                

                This slot is connected to a signal cleanup:

                    //Connect cleanup signal
                    QObject::connect(this, &clsMsgTrkr::cleanup, this, &clsMsgTrkr::onCleanup);
                

                This is also in the class constructor. I think I may have realised where the issue is, an instance of this class is created when a message is sent, I will look into how this is done now, I think modifying the constructor to emit a signal to create and start the timer would fix the issue.

                Kind Regards,
                Sy

                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  Is that class used in a threading context ?

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  0
                  • SPlattenS Offline
                    SPlattenS Offline
                    SPlatten
                    wrote on last edited by
                    #9

                    @SGaist , yes, messages are sent by a thread, but the actual way messages are sent is:

                            QJsonObject::iterator itrFound = objJSON.find(clsJSON::mscszMsgType);
                    
                            if ( itrFound != objJSON.end() ) {
                                const QJsonValueRef crobjMsgType = itrFound.value();
                                QString strMsgType(crobjMsgType.toString());
                    
                                if ( strMsgType.compare(clsJSON::mscszAck) != 0 ) {
                        //Create entry to monitor status of this message
                    //                new clsMsgTrkr(this, objJSON);
                                }
                            }
                        //Writes message to socket
                            emit write(objJSON);
                    

                    However as you can see above the call the new clsMsgTrkr is commented out so I'm wasn't actually using it anyway, so that's not the problem, I'm back to the original question, that's the only class that is using QTimer and it isn't used, so why am I getting those messages?

                    Kind Regards,
                    Sy

                    1 Reply Last reply
                    0
                    • SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      Possibly related to sockets.

                      Interested in AI ? www.idiap.ch
                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                      SPlattenS 1 Reply Last reply
                      0
                      • SGaistS SGaist

                        Possibly related to sockets.

                        SPlattenS Offline
                        SPlattenS Offline
                        SPlatten
                        wrote on last edited by SPlatten
                        #11

                        @SGaist , I've tried to make my threads as simply as possible and use signals, here is the body of a thread that handles the message sending:

                        void clsMsgSender::run() {    
                            //Default last state to connected as it won't be!
                            QTcpSocket::SocketState sckCurState;
                            while( mblnRun == true  ) {
                            //Sleep to allow a small cap between transmission
                                QThread::usleep(100);
                                quint16 uint16Port;
                        
                                if ( mpModule == nullptr || (uint16Port = mpModule->uint16Port()) == 0 ) {
                            //No module, do nothing!
                                    continue;
                                }
                                sckCurState = mpsckClient->state();
                        
                                if ( meSckState != sckCurState ) {
                                    meSckState = sckCurState;
                        
                                    if ( !(meSckState == QAbstractSocket::ConnectedState
                                        || meSckState == QAbstractSocket::ConnectingState) ) {
                                        emit tryToConnect(clsMsgSender::strGetLocalIP(), uint16Port);
                                    }
                                }
                                if ( meSckState != QAbstractSocket::ConnectedState ) {
                                    continue;
                                }
                                QJsonObject objJSON = objAnythingToDo();
                        
                                if ( objJSON.isEmpty() == true ) {
                            //Nothing to do...yet!
                                    continue;
                                }
                        //    //Look for a module name in the message
                        //        QJsonObject::iterator itrFound = objJSON.find(clsJSON::mscszMsgType);
                        
                        //        if ( itrFound != objJSON.end() ) {
                        //            const QJsonValueRef crobjMsgType = itrFound.value();
                        //            QString strMsgType(crobjMsgType.toString());
                        
                        //            if ( strMsgType.compare(clsJSON::mscszAck) != 0 ) {
                        //    //Create entry to monitor status of this message
                        ////                new clsMsgTrkr(this, objJSON);
                        //            }
                        //        }
                            //Writes message to socket
                                emit write(objJSON);
                            }
                            mblnStopped = true;
                        }
                        
                        

                        I use mutex's in the class methods:

                        QJsonObject clsMsgSender::objAnythingToDo() {
                            QMutexLocker lock(&mMutex);
                            QTcpSocket::SocketState sckState = mpsckClient->state();
                            QJsonObject objJSON;
                            if ( sckState == QAbstractSocket::ConnectedState ) {
                            //Check if there is anything waiting in the send later
                                objJSON = clsModule::objSendLater();
                        
                            //Anything waiting to send as soon as connection is established?
                                if ( objJSON.isEmpty() == true && mqueMsgsOut.isEmpty() != true ) {
                                    objJSON = mqueMsgsOut.dequeue();
                                }
                            }
                            return objJSON;
                        }
                        

                        Kind Regards,
                        Sy

                        SGaistS 1 Reply Last reply
                        0
                        • SPlattenS SPlatten

                          @SGaist , I've tried to make my threads as simply as possible and use signals, here is the body of a thread that handles the message sending:

                          void clsMsgSender::run() {    
                              //Default last state to connected as it won't be!
                              QTcpSocket::SocketState sckCurState;
                              while( mblnRun == true  ) {
                              //Sleep to allow a small cap between transmission
                                  QThread::usleep(100);
                                  quint16 uint16Port;
                          
                                  if ( mpModule == nullptr || (uint16Port = mpModule->uint16Port()) == 0 ) {
                              //No module, do nothing!
                                      continue;
                                  }
                                  sckCurState = mpsckClient->state();
                          
                                  if ( meSckState != sckCurState ) {
                                      meSckState = sckCurState;
                          
                                      if ( !(meSckState == QAbstractSocket::ConnectedState
                                          || meSckState == QAbstractSocket::ConnectingState) ) {
                                          emit tryToConnect(clsMsgSender::strGetLocalIP(), uint16Port);
                                      }
                                  }
                                  if ( meSckState != QAbstractSocket::ConnectedState ) {
                                      continue;
                                  }
                                  QJsonObject objJSON = objAnythingToDo();
                          
                                  if ( objJSON.isEmpty() == true ) {
                              //Nothing to do...yet!
                                      continue;
                                  }
                          //    //Look for a module name in the message
                          //        QJsonObject::iterator itrFound = objJSON.find(clsJSON::mscszMsgType);
                          
                          //        if ( itrFound != objJSON.end() ) {
                          //            const QJsonValueRef crobjMsgType = itrFound.value();
                          //            QString strMsgType(crobjMsgType.toString());
                          
                          //            if ( strMsgType.compare(clsJSON::mscszAck) != 0 ) {
                          //    //Create entry to monitor status of this message
                          ////                new clsMsgTrkr(this, objJSON);
                          //            }
                          //        }
                              //Writes message to socket
                                  emit write(objJSON);
                              }
                              mblnStopped = true;
                          }
                          
                          

                          I use mutex's in the class methods:

                          QJsonObject clsMsgSender::objAnythingToDo() {
                              QMutexLocker lock(&mMutex);
                              QTcpSocket::SocketState sckState = mpsckClient->state();
                              QJsonObject objJSON;
                              if ( sckState == QAbstractSocket::ConnectedState ) {
                              //Check if there is anything waiting in the send later
                                  objJSON = clsModule::objSendLater();
                          
                              //Anything waiting to send as soon as connection is established?
                                  if ( objJSON.isEmpty() == true && mqueMsgsOut.isEmpty() != true ) {
                                      objJSON = mqueMsgsOut.dequeue();
                                  }
                              }
                              return objJSON;
                          }
                          
                          SGaistS Offline
                          SGaistS Offline
                          SGaist
                          Lifetime Qt Champion
                          wrote on last edited by
                          #12

                          @SPlatten said in Timers cannot be ####### from another thread:

                          clsMsgSender

                          Is that a QThread subclass ?
                          Where do you create the socket ?

                          Interested in AI ? www.idiap.ch
                          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                          SPlattenS eyllanescE 2 Replies Last reply
                          0
                          • SGaistS SGaist

                            @SPlatten said in Timers cannot be ####### from another thread:

                            clsMsgSender

                            Is that a QThread subclass ?
                            Where do you create the socket ?

                            SPlattenS Offline
                            SPlattenS Offline
                            SPlatten
                            wrote on last edited by
                            #13

                            @SGaist, here is part of the prototype:

                                class clsMsgSender : public QObject {
                                Q_OBJECT
                                ...
                            }
                            

                            And the constructor:

                            clsMsgSender::clsMsgSender(clsModule* pModule)
                                                : mblnRun(true), mblnStopped(false)
                                                , meSckState(QAbstractSocket::ConnectedState)
                                                , mpModule(nullptr)
                                                , mpsckClient(nullptr)
                                                , mpThread(nullptr) {
                                setModule(pModule);
                                clsMsgSender::mspService = this;
                                QObject::connect(this, &clsMsgSender::tryToConnect
                                                ,this, &clsMsgSender::onTryToConnect, Qt::DirectConnection);
                                QObject::connect(this, &clsMsgSender::removeTrkrs
                                                ,this, &clsMsgSender::onRemoveTrkrs, Qt::DirectConnection);
                                QObject::connect(this, &clsMsgSender::sendJSON
                                                ,this, &clsMsgSender::onSendJSON, Qt::DirectConnection);
                                QObject::connect(this, &clsMsgSender::startService
                                                ,this, &clsMsgSender::onCreateMsgSndrThrd, Qt::DirectConnection);
                                QObject::connect(this, &clsMsgSender::write
                                                ,this, &clsMsgSender::onWrite, Qt::DirectConnection);
                                mpsckClient = new QTcpSocket(this);
                                QObject::connect(mpsckClient, &QTcpSocket::connected
                                                ,this, &clsMsgSender::onConnected);
                                QObject::connect(mpsckClient, &QAbstractSocket::errorOccurred
                                                ,this, &clsMsgSender::onErrorOccurred);
                                QObject::connect(mpsckClient, &QTcpSocket::disconnected
                                                ,this, &clsMsgSender::onDisconnected);
                                emit startService();
                            }
                            

                            And the slot onCreateMsgSndrThrd:

                            void clsMsgSender::onCreateMsgSndrThrd() {
                                if ( mpThread == nullptr ) {
                                    mpThread = new QThread;
                                    moveToThread(mpThread);
                                    QObject::connect(mpThread, &QThread::started, this, &clsMsgSender::run);
                                    mpThread->start();
                                }
                            }
                            

                            Kind Regards,
                            Sy

                            SGaistS 1 Reply Last reply
                            0
                            • SGaistS SGaist

                              @SPlatten said in Timers cannot be ####### from another thread:

                              clsMsgSender

                              Is that a QThread subclass ?
                              Where do you create the socket ?

                              eyllanescE Offline
                              eyllanescE Offline
                              eyllanesc
                              wrote on last edited by
                              #14

                              @SGaist I think that "mpsckClient" was created in the same where the QThread lives (probably in the constructor) but it is using it in the thread that manages the QThread (the run method)

                              If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

                              SPlattenS 1 Reply Last reply
                              0
                              • eyllanescE eyllanesc

                                @SGaist I think that "mpsckClient" was created in the same where the QThread lives (probably in the constructor) but it is using it in the thread that manages the QThread (the run method)

                                SPlattenS Offline
                                SPlattenS Offline
                                SPlatten
                                wrote on last edited by
                                #15

                                @eyllanesc , mpsckClient is created in the clsMsgSender constructor which is not in a thread.

                                Kind Regards,
                                Sy

                                SGaistS 1 Reply Last reply
                                0
                                • SPlattenS SPlatten

                                  @SGaist, here is part of the prototype:

                                      class clsMsgSender : public QObject {
                                      Q_OBJECT
                                      ...
                                  }
                                  

                                  And the constructor:

                                  clsMsgSender::clsMsgSender(clsModule* pModule)
                                                      : mblnRun(true), mblnStopped(false)
                                                      , meSckState(QAbstractSocket::ConnectedState)
                                                      , mpModule(nullptr)
                                                      , mpsckClient(nullptr)
                                                      , mpThread(nullptr) {
                                      setModule(pModule);
                                      clsMsgSender::mspService = this;
                                      QObject::connect(this, &clsMsgSender::tryToConnect
                                                      ,this, &clsMsgSender::onTryToConnect, Qt::DirectConnection);
                                      QObject::connect(this, &clsMsgSender::removeTrkrs
                                                      ,this, &clsMsgSender::onRemoveTrkrs, Qt::DirectConnection);
                                      QObject::connect(this, &clsMsgSender::sendJSON
                                                      ,this, &clsMsgSender::onSendJSON, Qt::DirectConnection);
                                      QObject::connect(this, &clsMsgSender::startService
                                                      ,this, &clsMsgSender::onCreateMsgSndrThrd, Qt::DirectConnection);
                                      QObject::connect(this, &clsMsgSender::write
                                                      ,this, &clsMsgSender::onWrite, Qt::DirectConnection);
                                      mpsckClient = new QTcpSocket(this);
                                      QObject::connect(mpsckClient, &QTcpSocket::connected
                                                      ,this, &clsMsgSender::onConnected);
                                      QObject::connect(mpsckClient, &QAbstractSocket::errorOccurred
                                                      ,this, &clsMsgSender::onErrorOccurred);
                                      QObject::connect(mpsckClient, &QTcpSocket::disconnected
                                                      ,this, &clsMsgSender::onDisconnected);
                                      emit startService();
                                  }
                                  

                                  And the slot onCreateMsgSndrThrd:

                                  void clsMsgSender::onCreateMsgSndrThrd() {
                                      if ( mpThread == nullptr ) {
                                          mpThread = new QThread;
                                          moveToThread(mpThread);
                                          QObject::connect(mpThread, &QThread::started, this, &clsMsgSender::run);
                                          mpThread->start();
                                      }
                                  }
                                  
                                  SGaistS Offline
                                  SGaistS Offline
                                  SGaist
                                  Lifetime Qt Champion
                                  wrote on last edited by
                                  #16

                                  @SPlatten move the socket creation in run. Sockets cannot be moved to other threads. They have to be created in the thread they will actually work in.

                                  Interested in AI ? www.idiap.ch
                                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                                  eyllanescE SPlattenS 2 Replies Last reply
                                  1
                                  • SGaistS SGaist

                                    @SPlatten move the socket creation in run. Sockets cannot be moved to other threads. They have to be created in the thread they will actually work in.

                                    eyllanescE Offline
                                    eyllanescE Offline
                                    eyllanesc
                                    wrote on last edited by
                                    #17

                                    @SGaist Exactly, that's what I meant.

                                    If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

                                    1 Reply Last reply
                                    0
                                    • SGaistS SGaist

                                      @SPlatten move the socket creation in run. Sockets cannot be moved to other threads. They have to be created in the thread they will actually work in.

                                      SPlattenS Offline
                                      SPlattenS Offline
                                      SPlatten
                                      wrote on last edited by
                                      #18

                                      @SGaist, @eyllanesc , do you mean:

                                      void clsMsgSender::run() {    
                                          mpsckClient = new QTcpSocket(this);
                                          QObject::connect(mpsckClient, &QTcpSocket::connected
                                                          ,this, &clsMsgSender::onConnected);
                                          QObject::connect(mpsckClient, &QAbstractSocket::errorOccurred
                                                          ,this, &clsMsgSender::onErrorOccurred);
                                          QObject::connect(mpsckClient, &QTcpSocket::disconnected
                                                          ,this, &clsMsgSender::onDisconnected);
                                          //Default last state to connected as it won't be!
                                          QTcpSocket::SocketState sckCurState;
                                          while( mblnRun == true  ) {
                                      ...
                                      

                                      Kind Regards,
                                      Sy

                                      1 Reply Last reply
                                      0
                                      • SPlattenS SPlatten

                                        @eyllanesc , mpsckClient is created in the clsMsgSender constructor which is not in a thread.

                                        SGaistS Offline
                                        SGaistS Offline
                                        SGaist
                                        Lifetime Qt Champion
                                        wrote on last edited by
                                        #19

                                        @SPlatten said in Timers cannot be ####### from another thread:

                                        @eyllanesc , mpsckClient is created in the clsMsgSender constructor which is not in a thread.

                                        Wrong, the object creation happens in the main thread.

                                        You always have at least one thread when you execute an application.

                                        Interested in AI ? www.idiap.ch
                                        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                                        SPlattenS 1 Reply Last reply
                                        1
                                        • SGaistS SGaist

                                          @SPlatten said in Timers cannot be ####### from another thread:

                                          @eyllanesc , mpsckClient is created in the clsMsgSender constructor which is not in a thread.

                                          Wrong, the object creation happens in the main thread.

                                          You always have at least one thread when you execute an application.

                                          SPlattenS Offline
                                          SPlattenS Offline
                                          SPlatten
                                          wrote on last edited by
                                          #20

                                          @SGaist , then that is exactly how it was done already since the object clsMsgSender is created in the main thread.

                                          Kind Regards,
                                          Sy

                                          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