Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. QTimers and QTcpSocket cannot be started/enabled from another thread error.
Forum Updated to NodeBB v4.3 + New Features

QTimers and QTcpSocket cannot be started/enabled from another thread error.

Scheduled Pinned Locked Moved Unsolved Mobile and Embedded
9 Posts 2 Posters 3.2k Views
  • 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 Offline
    S Offline
    seshu workemail
    wrote on last edited by
    #1

    I have 2 threads - 1. Main Thread and 2.Worker Thread.

    The worker thread is used for establishing a TCP connection with the server and reading and writing of data to/from the server. The run() for the worker thread is in its constructor. The obj for the worker thread is created in the main.cpp i.e. the main thread.
    I have declared QTcpSocket* socket and QTimer* timer in worker thread. And socket works perfectly fine but gives out the following tracing everytime I try to write:
    "QSocketNotifier: socket notifiers cannot be enabled from another thread"
    The timer starts properly, stops properly but doesn't start again when the worker thread goes back from the DISCONNECTED state to CONNECTED state via SET_CONNECTION state. It gives following error:
    QObject::killTimer: timers cannot be stopped from another thread
    QObject::startTimer: timers cannot be started from another thread

    along with:
    QObject: Cannot create children for a parent that is in a different thread.
    (Parent is QTcpSocket(0x159ea0), parent's thread is Thread(0x14f5b4), current thread is QThread(0x1541c0)

    I dont understand what is causing these errors since both the QTimer and QTcpSocket are declared and initiated in the worker thread.

    1 Reply Last reply
    0
    • jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by
      #2

      "The run() for the worker thread is in its constructor" - that sounds strange!
      Usually you start the thread by calling start() method.
      Do you call run() before or after you create QTcpSocket and QTimer instances?

      Actually you do not need to use threads for networking in Qt because it is asynchronous (non blocking).

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      S 1 Reply Last reply
      0
      • jsulmJ jsulm

        "The run() for the worker thread is in its constructor" - that sounds strange!
        Usually you start the thread by calling start() method.
        Do you call run() before or after you create QTcpSocket and QTimer instances?

        Actually you do not need to use threads for networking in Qt because it is asynchronous (non blocking).

        S Offline
        S Offline
        seshu workemail
        wrote on last edited by
        #3

        @jsulm
        I'm sorry about not being clear in my last description of the problem.

        The start() call for my worker thread is in its constructor.
        I do:
        //in the worker.h
        QTcpSocket socket;
        QTimer
        timer;
        //in the run() of worker.cpp
        socket = new QTcpSocket();
        timer = new QTimer();

        I have a doWork function which has a switch case statement with various states where:
        ..........
        CONNECTED_STATE:
        timer->start();
        DISCONNECTED_STATE:
        timer->stop();
        socket->disconnectFromHost();

        I needed 2 threads so that I do not need to block the GUI which will be coded in the main thread when my worker thread loops in the SET_CONNECTION state where it tries to establish connection in a blocking way etc.

        1 Reply Last reply
        0
        • jsulmJ Offline
          jsulmJ Offline
          jsulm
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Can you post your code?
          "QObject: Cannot create children for a parent that is in a different thread.
          (Parent is QTcpSocket(0x159ea0), parent's thread is Thread(0x14f5b4), current thread is QThread(0x1541c0)"
          Something is definitely wrong.

          https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          0
          • S Offline
            S Offline
            seshu workemail
            wrote on last edited by
            #5

            //worker thread ie named as Thread.cpp
            Thread::Thread()
            {
            qDebug()<<"YOU ARE IN THE THREAD CONSTRUCTOR\n";
            start();
            }
            void Thread::run()
            {

            qDebug() << "hello from worker thread " << thread()->currentThreadId();
            timer = new QTimer();
            timer->setInterval(5000);
            socket = new QTcpSocket();
            buffer = new QBuffer();//Creation of Buffer
            buffer->open(QIODevice::ReadWrite);

            connect(timer, SIGNAL(timeout()), this, SLOT(update()));
            connect(socket, SIGNAL(disconnected()), SLOT(TCPStatus()));

            s = INIT_STATE;
            doWork();
            exec();
            }

            void Thread::doWork() {
            qDebug() << "hello from doWork() " << thread()->currentThreadId();
            State k;
            switch(s)
            {
            case INIT_STATE:
            qDebug() << "INIT_STATE\n";
            //This state is intentionally coded with no break statement
            //so that the state machiene falls throught o the nex state
            //without any trigger.
            case SET_CONNECTION_STATE:
            label: while(true)
            {
            s = SET_CONNECTION_STATE;
            qDebug() << "SET_CONNECTION_STATE\n";
            socket->connectToHost("192.168.1.74",502);
            if(!socket->waitForConnected(5000)){
            qDebug()<<"Error creating socket: "<<socket->errorString();
            sleep(5);
            continue;
            }//end if
            else{
            break;
            }
            }//end while
            case CONNECTED_STATE:
            s = CONNECTED_STATE;
            qDebug()<<"CONNECTED_STATE";
            //start the timer
            timer->start();
            qDebug()<<"timer started :"<<thread()->currentThreadId();

            	break;
            
            	case DISCONNECTED_STATE:
            	s = DISCONNECTED_STATE;
            	qDebug() << "DISCONNECTED_STATE\n";
            	//release the resources.
            	socket->disconnectFromHost();
                timer->stop();
            	s = SET_CONNECTION_STATE;
            	goto label;
            	break;
            

            }//end switch case
            stateChange(k);
            }

            void Thread::TCPStatus()
            {
            qDebug() << "Thread::TCPStatus\n";

            if (socket->state() == QTcpSocket::ConnectedState)
            {
             qDebug() << "TCPStatus::state=CONNECTED\n";
            }
            else
            {
             qDebug() << "TCPStatus::state=DISCONNECTED\n";
             s = DISCONNECTED_STATE;
             doWork();
            }
            

            }

            void Thread::stateChange(enum State k)
            {
            if(k>s){
            qDebug() << "Thread::setState\n";
            s=k;
            doWork();
            }
            }

            void Thread::update(){
            qDebug() << "Thread::update()";
            }

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

              Cat you try to call start() outside of the constructor?
              I'm not sure whether calling start() inside the constructor of a thread class is supposed to work.

              https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              0
              • S Offline
                S Offline
                seshu workemail
                wrote on last edited by
                #7

                Yes I tried thread.start(); in the main.cpp but the behavour is same as before.

                1 Reply Last reply
                0
                • S Offline
                  S Offline
                  seshu workemail
                  wrote on last edited by
                  #8

                  I have found the following in the tracing:
                  //initially I have different thread ids:
                  hello from GUI thread 0x4c70056
                  hello from worker thread 0x535004a
                  //I trace out the thread id from doWork() and I get the worker thread id correctly
                  hello from doWork() 0x535004a
                  //I disconnect and reconnect. I get all the errors and the doWork() gives me the main thread id as the current thread id.
                  hello from doWork() 0x4c70056

                  1 Reply Last reply
                  0
                  • S Offline
                    S Offline
                    seshu workemail
                    wrote on last edited by
                    #9

                    I have found out what was wrong with my code:

                    It was a thread affinity issue.
                    I wasn't using QT:DirectConnection in my connect() and so the QTimer and QTcpsocket instance though declared in the worker thread have affinity to the main thread since the worker thread was instantiated and started in the main.cpp

                    Anyway, @jslum I really appreciate your help.

                    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