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. QThread, QUdpSocket non-blocking
Forum Updated to NodeBB v4.3 + New Features

QThread, QUdpSocket non-blocking

Scheduled Pinned Locked Moved Solved General and Desktop
11 Posts 3 Posters 5.9k Views 1 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.
  • PuntP Punt

    Hi guys,
    first, i'll try my best in English, so sorry if there's some mistakes.

    Here is my code :

    class threadCom : public QThread
    {
        Q_OBJECT
    public:
        explicit threadCom(QObject *parent = 0);
        void run();
    private:
        QUdpSocket *m_socketRec;
        void bind();
        QStack<QByteArray> *m_pileIP;
    
    public slots:
        void readPendingDatagrams();
    
    };
    
    
    void threadCom::bind(){
        if(m_socketRec->bind(m_address, m_portRec)){ //m_address & m_portRec are set don't worry :p
            std::cerr << "Connected" << std::endl;
            connect(m_socketRec, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams()));
        }
        else{
            std::cerr << "Fail" << std::endl;
        }
    }
    

    And in my thread,
    i would like to :

    • Wait for a new data in my QStack ( readPendingDatagrams add a QByteArray when there is a new frame in my socket)
    • or wait for a timeout if there is no frame on my QStack

    =>

    run(){
    
        forever{
             QTimer *timer_nb = new QTimer();
             timer_nb->start(500);
    
             // --- Wait for timeout or new frames in my QStack
             //then ....
        }
    }
    

    That's the idea..
    But i'm having trouble with threads (I'm new with this)
    I guess I should use waitForReadyRead( myTimeout ) ?

    I tried 50 different way, none was the good one...

    (Btw, I need to use Threads, because when I ask, a lot of people say I don't need threads to do that, but that's imposed !)

    JKSHJ Offline
    JKSHJ Offline
    JKSH
    Moderators
    wrote on last edited by
    #2

    Hi @Punt, and welcome to the Qt Dev Net!

    forever{
         QTimer *timer_nb = new QTimer();
    

    The forever loop will block the Qt event loop. If you want to use signals and slots, you cannot use forever.

    I tried 50 different way, none was the good one...

    Did you read the QThread documentation? There are some examples there: http://doc.qt.io/qt-5/qthread.html

    (Btw, I need to use Threads, because when I ask, a lot of people say I don't need threads to do that, but that's imposed !)

    Imposed by who? Why do you need to use threads?

    Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

    PuntP 1 Reply Last reply
    0
    • JKSHJ JKSH

      Hi @Punt, and welcome to the Qt Dev Net!

      forever{
           QTimer *timer_nb = new QTimer();
      

      The forever loop will block the Qt event loop. If you want to use signals and slots, you cannot use forever.

      I tried 50 different way, none was the good one...

      Did you read the QThread documentation? There are some examples there: http://doc.qt.io/qt-5/qthread.html

      (Btw, I need to use Threads, because when I ask, a lot of people say I don't need threads to do that, but that's imposed !)

      Imposed by who? Why do you need to use threads?

      PuntP Offline
      PuntP Offline
      Punt
      wrote on last edited by
      #3

      @JKSH said:

      Hi @Punt, and welcome to the Qt Dev Net!

      Thanks !

      The forever loop will block the Qt event loop. If you want to use signals and slots, you cannot use forever.

      y, I don't use anymore forever, I have to use exec() right ?

      Did you read the QThread documentation? There are some examples there: http://doc.qt.io/qt-5/qthread.html

      I did ! But I guess i'm lost with everything I read this morning x)

      (Btw, I need to use Threads, because when I ask, a lot of people say I don't need threads to do that, but that's imposed !)

      Imposed by who? Why do you need to use threads?

      Because I'll have a GUI, and I'll receive data to update my GUI, and I'll have to send data (with the state of my buttons on my GUI) => I'll have 2 threads, one for my UDP connexion, one for my GUI. these threads can be synchronized (When I received a new data, I signal my GUI's thread that he needs to do a loop)

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

        Qt networking is asynchronous so there is usually no need for multi-threading.

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

        PuntP 1 Reply Last reply
        0
        • jsulmJ jsulm

          Qt networking is asynchronous so there is usually no need for multi-threading.

          PuntP Offline
          PuntP Offline
          Punt
          wrote on last edited by
          #5
          run() //Of my UDP Thread
          {
              if(m_bloquant) //if blocking UDP connection
                  //wait for a new frame
              else // non-blocking 
                  //wait for a new frame OR a timeout
          
              //then ...
              //share the new frame with GUI's thread
              //(if my 2 threads are synchronized) : emit to my GUI's thread to loop (GUI's thread will share data with UDP's thread)
              //Send data (in another socket udp)
              
              //loop
          
          }
          

          that's what I want to do !

          1 Reply Last reply
          0
          • PuntP Offline
            PuntP Offline
            Punt
            wrote on last edited by
            #6

            Another try :

            void threadCom::run(){ 
                bind(); // new QUdpSocket() & bind
            
                if(!m_bloquant){ //if non-blocking
                    m_timer_b = new QTimer(); // QTimer
                    connect(m_timer_b, SIGNAL(timeout()), this, SLOT(startCycle())); // One cycle + reset timer
                    m_timer_b->start(m_timeout_b); 
                }
                connect(m_socketRec, SIGNAL(readyRead()), SLOT(readPendingDatagrams())); 
                    exec();
            }
            
            void threadCom::startCycle(){
                if(!m_pileIP->isEmpty()) // if data in QStack
                {
                    m_dataShared->setData(m_pileIP->pop());  //share data
                    m_pileIP->clear();
                }
                if(m_sync) //if SYNC with GUI's thread
                    emit needTraitement(); 
                sendDatagrams(); //Just a cout but soon QUdpSocket_sender.write(something)
                if(!m_bloquant) // if non-blocking
                    m_timer_b->start(m_timeout_b);  //reset timeout
            }
            

            and in ReadPendingDatagrams, I added a reset timeout too.

            But this is looping just one time and doing nothing more ...

            1 Reply Last reply
            0
            • PuntP Punt

              @JKSH said:

              Hi @Punt, and welcome to the Qt Dev Net!

              Thanks !

              The forever loop will block the Qt event loop. If you want to use signals and slots, you cannot use forever.

              y, I don't use anymore forever, I have to use exec() right ?

              Did you read the QThread documentation? There are some examples there: http://doc.qt.io/qt-5/qthread.html

              I did ! But I guess i'm lost with everything I read this morning x)

              (Btw, I need to use Threads, because when I ask, a lot of people say I don't need threads to do that, but that's imposed !)

              Imposed by who? Why do you need to use threads?

              Because I'll have a GUI, and I'll receive data to update my GUI, and I'll have to send data (with the state of my buttons on my GUI) => I'll have 2 threads, one for my UDP connexion, one for my GUI. these threads can be synchronized (When I received a new data, I signal my GUI's thread that he needs to do a loop)

              JKSHJ Offline
              JKSHJ Offline
              JKSH
              Moderators
              wrote on last edited by
              #7

              @Punt said:

              y, I don't use anymore forever, I have to use exec() right ?

              Right. If you want to use signals and slots, you must use exec(), not forever.

              I did ! But I guess i'm lost with everything I read this morning x)

              Threads can be tricky. I recommend that you don't use threads, unless you really really have to.

              Because I'll have a GUI, and I'll receive data to update my GUI, and I'll have to send data (with the state of my buttons on my GUI) => I'll have 2 threads, one for my UDP connexion, one for my GUI. these threads can be synchronized (When I received a new data, I signal my GUI's thread that he needs to do a loop)

              Well, like @jsulm said, Qt has the power to let you send/receive UDP data AND update the GUI using only one thread :)

              See these simple examples:

              • http://doc.qt.io/qt-5/qtnetwork-multicastreceiver-example.html
              • http://doc.qt.io/qt-5/qtnetwork-multicastsender-example.html

              (Or, in Qt Creator, search for the "Broadcast Sender" and "Broadcast Receiver" examples)

              Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

              PuntP 1 Reply Last reply
              0
              • JKSHJ JKSH

                @Punt said:

                y, I don't use anymore forever, I have to use exec() right ?

                Right. If you want to use signals and slots, you must use exec(), not forever.

                I did ! But I guess i'm lost with everything I read this morning x)

                Threads can be tricky. I recommend that you don't use threads, unless you really really have to.

                Because I'll have a GUI, and I'll receive data to update my GUI, and I'll have to send data (with the state of my buttons on my GUI) => I'll have 2 threads, one for my UDP connexion, one for my GUI. these threads can be synchronized (When I received a new data, I signal my GUI's thread that he needs to do a loop)

                Well, like @jsulm said, Qt has the power to let you send/receive UDP data AND update the GUI using only one thread :)

                See these simple examples:

                • http://doc.qt.io/qt-5/qtnetwork-multicastreceiver-example.html
                • http://doc.qt.io/qt-5/qtnetwork-multicastsender-example.html

                (Or, in Qt Creator, search for the "Broadcast Sender" and "Broadcast Receiver" examples)

                PuntP Offline
                PuntP Offline
                Punt
                wrote on last edited by Punt
                #8

                @JKSH

                Ok, I'm not using anymore QThreads for my UDP connection,
                but now I need a class with a QThread which works like that :

                run(){
                    if( myapp.isSync() )
                        //wait for a signal from my UDP class
                    
                    ...
                    //treatment
                    ...    
                    
                    
                    if( ! myapp.isSync() )
                        msleep( timeout );
                }
                

                Which mean, if my UDP class & this threads are synchronized, I wait a signal from my UDP class to start a loop (and then wait for another signal, etc..... = exec() ?)
                How do I do that ?

                JKSHJ 1 Reply Last reply
                0
                • PuntP Punt

                  @JKSH

                  Ok, I'm not using anymore QThreads for my UDP connection,
                  but now I need a class with a QThread which works like that :

                  run(){
                      if( myapp.isSync() )
                          //wait for a signal from my UDP class
                      
                      ...
                      //treatment
                      ...    
                      
                      
                      if( ! myapp.isSync() )
                          msleep( timeout );
                  }
                  

                  Which mean, if my UDP class & this threads are synchronized, I wait a signal from my UDP class to start a loop (and then wait for another signal, etc..... = exec() ?)
                  How do I do that ?

                  JKSHJ Offline
                  JKSHJ Offline
                  JKSH
                  Moderators
                  wrote on last edited by
                  #9

                  @Punt said:

                  if my UDP class & this threads are synchronized

                  Can you describe how you planned to synchronize your threads?

                  run(){
                      if( myapp.isSync() )
                          //wait for a signal from my UDP class
                      
                      ...
                      //treatment
                      ...    
                      
                      
                      if( ! myapp.isSync() )
                          msleep( timeout );
                  }
                  

                  You just need to use event-driven programming.

                  class UdpSignalHandler : public QObject
                  {
                      Q_OBJECT
                  
                      //...
                  
                  public slots:
                       void doTreatment {
                          //treatment
                      }
                  };
                  
                  int main(int argc, char **argv) {
                  
                      QApplication app(argc, argv);
                  
                      // ...
                  
                      auto handler = new UdpSignalHandler;
                  
                      QObject::connect(udpSocket, &QUdpSocket::readyRead,
                              handler, &UdpSignalHandler::doTreatment);
                  
                      /*--------------------------*/
                      /* This part is optional!   */
                      auto thread = new QThread;
                      handler->moveToThread(thread);
                      thread->start();
                      /*--------------------------*/
                  
                      // ...
                  
                      app.exec();
                  }
                  

                  That's it. Now, every time the UDP socket emits a signal, your UdpSignalHandler will run the doTreatment() function in the other thread. Also, you don't need to ask your thread to sleep. It will automatically sleep when there are no signals.

                  Finally, I still don't think you need threads. if you delete the code that I marked "optional", your program will still run -- all in the main thread.

                  (Note: My code doesn't include deleting the objects. You must handle this yourself)

                  Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                  PuntP 1 Reply Last reply
                  0
                  • JKSHJ JKSH

                    @Punt said:

                    if my UDP class & this threads are synchronized

                    Can you describe how you planned to synchronize your threads?

                    run(){
                        if( myapp.isSync() )
                            //wait for a signal from my UDP class
                        
                        ...
                        //treatment
                        ...    
                        
                        
                        if( ! myapp.isSync() )
                            msleep( timeout );
                    }
                    

                    You just need to use event-driven programming.

                    class UdpSignalHandler : public QObject
                    {
                        Q_OBJECT
                    
                        //...
                    
                    public slots:
                         void doTreatment {
                            //treatment
                        }
                    };
                    
                    int main(int argc, char **argv) {
                    
                        QApplication app(argc, argv);
                    
                        // ...
                    
                        auto handler = new UdpSignalHandler;
                    
                        QObject::connect(udpSocket, &QUdpSocket::readyRead,
                                handler, &UdpSignalHandler::doTreatment);
                    
                        /*--------------------------*/
                        /* This part is optional!   */
                        auto thread = new QThread;
                        handler->moveToThread(thread);
                        thread->start();
                        /*--------------------------*/
                    
                        // ...
                    
                        app.exec();
                    }
                    

                    That's it. Now, every time the UDP socket emits a signal, your UdpSignalHandler will run the doTreatment() function in the other thread. Also, you don't need to ask your thread to sleep. It will automatically sleep when there are no signals.

                    Finally, I still don't think you need threads. if you delete the code that I marked "optional", your program will still run -- all in the main thread.

                    (Note: My code doesn't include deleting the objects. You must handle this yourself)

                    PuntP Offline
                    PuntP Offline
                    Punt
                    wrote on last edited by Punt
                    #10

                    @JKSH
                    I need a thread because this thread can work "not synchronized" with my UDP class.

                    Here, when I receive a signal, I'll have to check if there is new datas shared by both class, if so treat them. Then my UdpSignalHandler will update my GUI, share other datas(the state of GUI's button for example) with my UDP class,

                    But if this is not-synchronized, my UdpSignalHandler will have to do all of that, all the time with a little sleep().²

                    JKSHJ 1 Reply Last reply
                    0
                    • PuntP Punt

                      @JKSH
                      I need a thread because this thread can work "not synchronized" with my UDP class.

                      Here, when I receive a signal, I'll have to check if there is new datas shared by both class, if so treat them. Then my UdpSignalHandler will update my GUI, share other datas(the state of GUI's button for example) with my UDP class,

                      But if this is not-synchronized, my UdpSignalHandler will have to do all of that, all the time with a little sleep().²

                      JKSHJ Offline
                      JKSHJ Offline
                      JKSH
                      Moderators
                      wrote on last edited by JKSH
                      #11

                      @Punt said:

                      I need a thread because this thread can work "not synchronized" with my UDP class.

                      Sorry, I don't quite understand. Can you give an example of:

                      1. When the two are "synchronized"?
                      2. When the two are "not synchronized"?

                      Here, when I receive a signal, I'll have to check if there is new datas shared by both class, if so treat them.

                      The QUdpSocket will only emit the signal when there is new data, right?

                      If there is no new data, then UdpSignalHandler::doTreatment() will not run.

                      Then my UdpSignalHandler will update my GUI, share other datas(the state of GUI's button for example) with my UDP class

                      Note: If your UdpSignalHandler lives in another thread, then it is not allowed to read/write the GUI directly. For example, you must not call QLabel::setText() from another thread; you must only call it from the main thread.

                      If the UdpSignalHandler wants to update the GUI, it must emit a signal. Then, let a GUI object's slot update the GUI.

                      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                      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