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 5.4k 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.
  • S SGaist
    12 Jan 2021, 18:07

    Possibly related to sockets.

    S Offline
    S Offline
    SPlatten
    wrote on 12 Jan 2021, 18:11 last edited by SPlatten 1 Dec 2021, 18:13
    #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

    S 1 Reply Last reply 12 Jan 2021, 18:13
    0
    • S SPlatten
      12 Jan 2021, 18: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;
      }
      
      S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 12 Jan 2021, 18:13 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

      S E 2 Replies Last reply 12 Jan 2021, 18:17
      0
      • S SGaist
        12 Jan 2021, 18:13

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

        clsMsgSender

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

        S Offline
        S Offline
        SPlatten
        wrote on 12 Jan 2021, 18:17 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

        S 1 Reply Last reply 12 Jan 2021, 18:20
        0
        • S SGaist
          12 Jan 2021, 18:13

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

          clsMsgSender

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

          E Offline
          E Offline
          eyllanesc
          wrote on 12 Jan 2021, 18:18 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.

          S 1 Reply Last reply 12 Jan 2021, 18:19
          0
          • E eyllanesc
            12 Jan 2021, 18:18

            @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)

            S Offline
            S Offline
            SPlatten
            wrote on 12 Jan 2021, 18:19 last edited by
            #15

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

            Kind Regards,
            Sy

            S 1 Reply Last reply 12 Jan 2021, 18:23
            0
            • S SPlatten
              12 Jan 2021, 18:17

              @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();
                  }
              }
              
              S Offline
              S Offline
              SGaist
              Lifetime Qt Champion
              wrote on 12 Jan 2021, 18:20 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

              E S 2 Replies Last reply 12 Jan 2021, 18:20
              1
              • S SGaist
                12 Jan 2021, 18:20

                @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.

                E Offline
                E Offline
                eyllanesc
                wrote on 12 Jan 2021, 18:20 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
                • S SGaist
                  12 Jan 2021, 18:20

                  @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.

                  S Offline
                  S Offline
                  SPlatten
                  wrote on 12 Jan 2021, 18:22 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
                  • S SPlatten
                    12 Jan 2021, 18:19

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

                    S Offline
                    S Offline
                    SGaist
                    Lifetime Qt Champion
                    wrote on 12 Jan 2021, 18:23 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

                    S 1 Reply Last reply 12 Jan 2021, 18:27
                    1
                    • S SGaist
                      12 Jan 2021, 18:23

                      @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.

                      S Offline
                      S Offline
                      SPlatten
                      wrote on 12 Jan 2021, 18:27 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
                      • S Offline
                        S Offline
                        SGaist
                        Lifetime Qt Champion
                        wrote on 12 Jan 2021, 18:28 last edited by
                        #21

                        And that is the issue. You are thus creating your socket in the main thread as well.

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

                        S 1 Reply Last reply 12 Jan 2021, 18:29
                        0
                        • S SGaist
                          12 Jan 2021, 18:28

                          And that is the issue. You are thus creating your socket in the main thread as well.

                          S Offline
                          S Offline
                          SPlatten
                          wrote on 12 Jan 2021, 18:29 last edited by SPlatten 1 Dec 2021, 18:35
                          #22

                          @SGaist , sorry, I'm not sure why you say that, the class clsMsgSender is not a socket. If you mean that:

                          mpsckClient = new QTcpSocket(this);
                          

                          Is that the problem? because this is in the clsMsgSender constructor, then please explain what I should do because I suggested moving it into the thread and the response was no.

                          Can you please clarify what I'm doing wrong and how to fix it?

                          Kind Regards,
                          Sy

                          1 Reply Last reply
                          0
                          • C Offline
                            C Offline
                            Christian Ehrlicher
                            Lifetime Qt Champion
                            wrote on 12 Jan 2021, 18:40 last edited by
                            #23

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

                            new QTcpSocket(this);

                            This creates an object with the parent in the main thread. And since a child must be in the same thread as the parent...
                            Don't pass this as parent and delete it by your own.

                            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
                            1
                            • S Offline
                              S Offline
                              SGaist
                              Lifetime Qt Champion
                              wrote on 12 Jan 2021, 18:51 last edited by
                              #24

                              @Christian-Ehrlicher for sockets you have to go one step further and ensure it's created in the thread that will actually use it.

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

                              S 1 Reply Last reply 12 Jan 2021, 19:41
                              1
                              • S SGaist
                                12 Jan 2021, 18:51

                                @Christian-Ehrlicher for sockets you have to go one step further and ensure it's created in the thread that will actually use it.

                                S Offline
                                S Offline
                                SPlatten
                                wrote on 12 Jan 2021, 19:41 last edited by SPlatten 1 Dec 2021, 19:44
                                #25

                                Obviously I have a lot to learn where Qt threads are concerned, can someone point me to some relevant thread & socket tutorials or documentation?

                                I will take a closer look at fortuneserver and fortuneclient.

                                Kind Regards,
                                Sy

                                1 Reply Last reply
                                0
                                • S Offline
                                  S Offline
                                  SGaist
                                  Lifetime Qt Champion
                                  wrote on 12 Jan 2021, 19:44 last edited by
                                  #26

                                  Start with the QThread. There are several other chapters linked from the details of the class.

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

                                  S 1 Reply Last reply 13 Jan 2021, 07:58
                                  1
                                  • S SGaist
                                    12 Jan 2021, 19:44

                                    Start with the QThread. There are several other chapters linked from the details of the class.

                                    S Offline
                                    S Offline
                                    SPlatten
                                    wrote on 13 Jan 2021, 07:58 last edited by SPlatten
                                    #27

                                    @SGaist , I've just read the details on QThread and I didn't see anything specifically regarding the use of Sockets. I then found this when searching online:

                                    https://forum.qt.io/topic/57753/qtcpsocket-and-qthread
                                    Obviously you are familiar with this one.

                                    https://stackoverflow.com/questions/34641732/qtcpsocket-handling-in-another-qthread
                                    Not sure what the conclusion of the above was...

                                    https://www.bogotobogo.com/Qt/Qt5_QTcpServer_Multithreaded_Client_Server.php
                                    Working through this....

                                    I must say the approach the last link takes is exactly the way I started, with sub-classing my listening class from QTcpServer, however after several posts here advising not to do this I changed my class.

                                    Kind Regards,
                                    Sy

                                    1 Reply Last reply
                                    0

                                    20/27

                                    12 Jan 2021, 18:27

                                    • Login

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