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. Minimal example of proper way of forever-running server like QUdpSocket

Minimal example of proper way of forever-running server like QUdpSocket

Scheduled Pinned Locked Moved Unsolved General and Desktop
qfutureqtconcurrent
16 Posts 6 Posters 1.7k 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.
  • C Offline
    C Offline
    Christian Ehrlicher
    Lifetime Qt Champion
    wrote on 5 May 2021, 12:15 last edited by
    #7

    @perry_blueberry said in Minimal example of proper way of forever-running server like QUdpSocket:

    I am not trying to implement a UDP server. I am trying to implement my own (CAN). Through continually polling for messages I can get new messages with the library I'm using so for that to work it would need to run in some sort of therad. What that documentation shows is what I want the API for my own server to look like.

    So what's wrong with my first comment then? Use a separate QThread and properly close it on exit instead QtConcurrent::run() which is not designed for this usecase.

    Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
    Visit the Qt Academy at https://academy.qt.io/catalog

    P 1 Reply Last reply 5 May 2021, 13:00
    0
    • C Christian Ehrlicher
      5 May 2021, 12:15

      @perry_blueberry said in Minimal example of proper way of forever-running server like QUdpSocket:

      I am not trying to implement a UDP server. I am trying to implement my own (CAN). Through continually polling for messages I can get new messages with the library I'm using so for that to work it would need to run in some sort of therad. What that documentation shows is what I want the API for my own server to look like.

      So what's wrong with my first comment then? Use a separate QThread and properly close it on exit instead QtConcurrent::run() which is not designed for this usecase.

      P Offline
      P Offline
      perry_blueberry
      wrote on 5 May 2021, 13:00 last edited by
      #8

      @Christian-Ehrlicher
      I have looked at the examples. From the second example I have this

      //mainwindow.cpp
      #include "mainwindow.h"
      #include "ui_mainwindow.h"
      #include "WorkerThread.h"
      #include <QDebug>
      
      MainWindow::MainWindow(QWidget *parent)
          : QMainWindow(parent)
          , ui(new Ui::MainWindow)
      {
          ui->setupUi(this);
      
          WorkerThread *workerThread = new WorkerThread();
          connect(workerThread, &WorkerThread::resultReady, this, &MainWindow::handleResult);
          connect(workerThread, &WorkerThread::finished, workerThread, &QObject::deleteLater);
          workerThread->start();
      }
      
      MainWindow::~MainWindow()
      {
          delete ui;
      }
      
      void MainWindow::handleResult(const QString &s)
      {
          qDebug() << "Got results";
      }
      
      //WorkerThread.h
      #ifndef WORKERTHREAD_H
      #define WORKERTHREAD_H
      #include <QThread>
      class WorkerThread : public QThread
      {
          Q_OBJECT
          void run() override {
              QString result;
              /* ... here is the expensive or blocking operation ... */
              emit resultReady(result);
              this->exec();
          }
      signals:
          void resultReady(const QString &s);
      };
      #endif // WORKERTHREAD_H
      
      

      From this I see Got results one time. The documentation states that using exec() inside run I should be able to event loop this and get it to run many times but that doesn't work. I guess I'm doing something fundamentally wrong here? Putting while(true) causes the same issue as before where the program cannot exit without a crash.

      K 1 Reply Last reply 5 May 2021, 13:18
      0
      • P perry_blueberry
        5 May 2021, 13:00

        @Christian-Ehrlicher
        I have looked at the examples. From the second example I have this

        //mainwindow.cpp
        #include "mainwindow.h"
        #include "ui_mainwindow.h"
        #include "WorkerThread.h"
        #include <QDebug>
        
        MainWindow::MainWindow(QWidget *parent)
            : QMainWindow(parent)
            , ui(new Ui::MainWindow)
        {
            ui->setupUi(this);
        
            WorkerThread *workerThread = new WorkerThread();
            connect(workerThread, &WorkerThread::resultReady, this, &MainWindow::handleResult);
            connect(workerThread, &WorkerThread::finished, workerThread, &QObject::deleteLater);
            workerThread->start();
        }
        
        MainWindow::~MainWindow()
        {
            delete ui;
        }
        
        void MainWindow::handleResult(const QString &s)
        {
            qDebug() << "Got results";
        }
        
        //WorkerThread.h
        #ifndef WORKERTHREAD_H
        #define WORKERTHREAD_H
        #include <QThread>
        class WorkerThread : public QThread
        {
            Q_OBJECT
            void run() override {
                QString result;
                /* ... here is the expensive or blocking operation ... */
                emit resultReady(result);
                this->exec();
            }
        signals:
            void resultReady(const QString &s);
        };
        #endif // WORKERTHREAD_H
        
        

        From this I see Got results one time. The documentation states that using exec() inside run I should be able to event loop this and get it to run many times but that doesn't work. I guess I'm doing something fundamentally wrong here? Putting while(true) causes the same issue as before where the program cannot exit without a crash.

        K Offline
        K Offline
        KroMignon
        wrote on 5 May 2021, 13:18 last edited by KroMignon 5 May 2021, 13:18
        #9

        @perry_blueberry said in Minimal example of proper way of forever-running server like QUdpSocket:

        From this I see Got results one time. The documentation states that using exec() inside run I should be able to event loop this and get it to run many times but that doesn't work. I guess I'm doing something fundamentally wrong here? Putting while(true) causes the same issue as before where the program cannot exit without a crash.

        I don't want to hurt you, but your QThread usage can not work as it is.
        You should never sub-class QThread, especially if you want to use it in combination with QObject:

        • https://doc.qt.io/qt-5/qthread.html#details : "new slots should not be implemented directly into a subclassed QThread."
        • https://www.vikingsoftware.com/how-to-use-qthread-properly/

        I don't really understand what you want to achieve, so I can only guess.
        Correct me if I am wrong.

        My understanding, is that you want to perform a "heavy computing" outside the main thread.
        For this kind of purpose, I would recommend you to use QtConcurrent::run() => https://doc.qt.io/qt-5/qtconcurrentrun.html

        It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

        P 1 Reply Last reply 5 May 2021, 13:48
        0
        • K KroMignon
          5 May 2021, 13:18

          @perry_blueberry said in Minimal example of proper way of forever-running server like QUdpSocket:

          From this I see Got results one time. The documentation states that using exec() inside run I should be able to event loop this and get it to run many times but that doesn't work. I guess I'm doing something fundamentally wrong here? Putting while(true) causes the same issue as before where the program cannot exit without a crash.

          I don't want to hurt you, but your QThread usage can not work as it is.
          You should never sub-class QThread, especially if you want to use it in combination with QObject:

          • https://doc.qt.io/qt-5/qthread.html#details : "new slots should not be implemented directly into a subclassed QThread."
          • https://www.vikingsoftware.com/how-to-use-qthread-properly/

          I don't really understand what you want to achieve, so I can only guess.
          Correct me if I am wrong.

          My understanding, is that you want to perform a "heavy computing" outside the main thread.
          For this kind of purpose, I would recommend you to use QtConcurrent::run() => https://doc.qt.io/qt-5/qtconcurrentrun.html

          P Offline
          P Offline
          perry_blueberry
          wrote on 5 May 2021, 13:48 last edited by
          #10

          @KroMignon
          No worries, I am here to learn :)
          But I have to say this keeps on getting more confusing. The example I posted above is taken almost exactly line-by-line from the second example in the Qt documentation that you linked. I have only taken the controller part of it and put it in mainwindow. And it says In that example, the thread will exit after the run function has returned. There will not be any event loop running in the thread unless you call exec(). which makes it seem like you can have this kind of server by calling exec in run (putting it in run is mentioned somewhere close in the documentation).

          What I want to achieve is an asynchronous server that emits a signal when something is ready to be read. This is a very common way to implement some kind of server in many languages and frameworks that I've seen. A server doesn't run to conclusion and only gives results intermittently so it has to be allowed to run forever somehow while producing new results when they arrive.

          1 Reply Last reply
          0
          • P Offline
            P Offline
            perry_blueberry
            wrote on 5 May 2021, 14:05 last edited by
            #11

            To avoid confusion, when I say server I want to mention that I don't mean a web server or UDP server. I simply mean something that is blocking on some sort of connection to listen for some data. When that data comes it should make the data available for the rest of the application and then go to sleep again until there is something new to read.

            K 1 Reply Last reply 5 May 2021, 14:17
            0
            • N Offline
              N Offline
              nagesh
              wrote on 5 May 2021, 14:16 last edited by nagesh 5 May 2021, 14:17
              #12

              @perry_blueberry I suggest for your requirement implement ion like this is most suited rather than subclassing thread..
              connect required slot to socket ready read signal and
              In the slot read the data and emit the read data.

              Implement the above functionality in the class..
              Call it as Worker class. And move this class instance to thread using movetoThread()

              https://doc.qt.io/qt-5/qthread.html
              Use the first example in the link which suggests using moveToThread()

              P 1 Reply Last reply 5 May 2021, 14:55
              0
              • P perry_blueberry
                5 May 2021, 14:05

                To avoid confusion, when I say server I want to mention that I don't mean a web server or UDP server. I simply mean something that is blocking on some sort of connection to listen for some data. When that data comes it should make the data available for the rest of the application and then go to sleep again until there is something new to read.

                K Offline
                K Offline
                KroMignon
                wrote on 5 May 2021, 14:17 last edited by KroMignon 5 May 2021, 14:17
                #13

                @perry_blueberry said in Minimal example of proper way of forever-running server like QUdpSocket:

                When that data comes it should make the data available for the rest of the application and then go to sleep again until there is something new to read.

                The Qt documentation is very huge, and some examples are out-dated.

                Qt is an asynchronous framework, almost all Qt class handle this for you.
                For example:

                • QTcpSocket / QTcpServer
                • QUdpSocket
                • QSerialPort
                • etc.

                All those classes handle the "blocking logic" in background and triggers signals "when something happens".
                For example for QTcpSocket there are connected(), disconnected(), bytesWritten(), readyRead(), etc.

                So there is no need to use additional thread for this.

                Again, depending on what you want to do there are many strategies you can use for doing things outside from main thread:

                • for single operations, the simplest way is to use QtConcurrent::run() (maybe in combination with QFutureWatcher()
                • or using a "worker class", and using moveToThread() to run it in a background thread

                It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                1 Reply Last reply
                2
                • N nagesh
                  5 May 2021, 14:16

                  @perry_blueberry I suggest for your requirement implement ion like this is most suited rather than subclassing thread..
                  connect required slot to socket ready read signal and
                  In the slot read the data and emit the read data.

                  Implement the above functionality in the class..
                  Call it as Worker class. And move this class instance to thread using movetoThread()

                  https://doc.qt.io/qt-5/qthread.html
                  Use the first example in the link which suggests using moveToThread()

                  P Offline
                  P Offline
                  perry_blueberry
                  wrote on 5 May 2021, 14:55 last edited by
                  #14

                  @nagesh said in Minimal example of proper way of forever-running server like QUdpSocket:

                  @perry_blueberry I suggest for your requirement implement ion like this is most suited rather than subclassing thread..
                  connect required slot to socket ready read signal and
                  In the slot read the data and emit the read data.

                  Implement the above functionality in the class..
                  Call it as Worker class. And move this class instance to thread using movetoThread()

                  https://doc.qt.io/qt-5/qthread.html
                  Use the first example in the link which suggests using moveToThread()

                  I think I understand what you are saying; subclassing should be avoided for QThread. I will take a look at the links posted in this thread to get a better understanding of the intricacies.

                  @KroMignon said in Minimal example of proper way of forever-running server like QUdpSocket:

                  @perry_blueberry said in Minimal example of proper way of forever-running server like QUdpSocket:

                  When that data comes it should make the data available for the rest of the application and then go to sleep again until there is something new to read.

                  The Qt documentation is very huge, and some examples are out-dated.

                  Qt is an asynchronous framework, almost all Qt class handle this for you.
                  For example:

                  • QTcpSocket / QTcpServer
                  • QUdpSocket
                  • QSerialPort
                  • etc.

                  All those classes handle the "blocking logic" in background and triggers signals "when something happens".
                  For example for QTcpSocket there are connected(), disconnected(), bytesWritten(), readyRead(), etc.

                  So there is no need to use additional thread for this.

                  Again, depending on what you want to do there are many strategies you can use for doing things outside from main thread:

                  • for single operations, the simplest way is to use QtConcurrent::run() (maybe in combination with QFutureWatcher()
                  • or using a "worker class", and using moveToThread() to run it in a background thread

                  My case worked better as a QThread because it is very similar QTcpSocket and the other classes you listed. It was actually shutting down properly in the example I posted above. The issue was that I hadn't put any sleep in between the calls to qDebug so it quickly overtook the CPU. So everything seems to work as expected.

                  To sum up:
                  My first misunderstanding was that I was trying to use QtConcurrent::run which is apparently best suited for single operations. QThread seems to be the right use for a server.
                  I also misunderstood the meaning of exec. I thought it was a "magic" operator that would call run recursively (or something like that) when put at the end of run but it seems to have the purpose of starting the event loop which in turn means starting run. In the end what this boils down to is that I hadn't read the API properly and thinks work more-or-less as expected when comparing to other frameworks.

                  I haven't read it yet but https://www.toptal.com/qt/qt-multithreading-c-plus-plus seems like a good additional resource on the topic (for other people who might be stumbling onto the same issue).

                  K 1 Reply Last reply 5 May 2021, 15:00
                  0
                  • P perry_blueberry
                    5 May 2021, 14:55

                    @nagesh said in Minimal example of proper way of forever-running server like QUdpSocket:

                    @perry_blueberry I suggest for your requirement implement ion like this is most suited rather than subclassing thread..
                    connect required slot to socket ready read signal and
                    In the slot read the data and emit the read data.

                    Implement the above functionality in the class..
                    Call it as Worker class. And move this class instance to thread using movetoThread()

                    https://doc.qt.io/qt-5/qthread.html
                    Use the first example in the link which suggests using moveToThread()

                    I think I understand what you are saying; subclassing should be avoided for QThread. I will take a look at the links posted in this thread to get a better understanding of the intricacies.

                    @KroMignon said in Minimal example of proper way of forever-running server like QUdpSocket:

                    @perry_blueberry said in Minimal example of proper way of forever-running server like QUdpSocket:

                    When that data comes it should make the data available for the rest of the application and then go to sleep again until there is something new to read.

                    The Qt documentation is very huge, and some examples are out-dated.

                    Qt is an asynchronous framework, almost all Qt class handle this for you.
                    For example:

                    • QTcpSocket / QTcpServer
                    • QUdpSocket
                    • QSerialPort
                    • etc.

                    All those classes handle the "blocking logic" in background and triggers signals "when something happens".
                    For example for QTcpSocket there are connected(), disconnected(), bytesWritten(), readyRead(), etc.

                    So there is no need to use additional thread for this.

                    Again, depending on what you want to do there are many strategies you can use for doing things outside from main thread:

                    • for single operations, the simplest way is to use QtConcurrent::run() (maybe in combination with QFutureWatcher()
                    • or using a "worker class", and using moveToThread() to run it in a background thread

                    My case worked better as a QThread because it is very similar QTcpSocket and the other classes you listed. It was actually shutting down properly in the example I posted above. The issue was that I hadn't put any sleep in between the calls to qDebug so it quickly overtook the CPU. So everything seems to work as expected.

                    To sum up:
                    My first misunderstanding was that I was trying to use QtConcurrent::run which is apparently best suited for single operations. QThread seems to be the right use for a server.
                    I also misunderstood the meaning of exec. I thought it was a "magic" operator that would call run recursively (or something like that) when put at the end of run but it seems to have the purpose of starting the event loop which in turn means starting run. In the end what this boils down to is that I hadn't read the API properly and thinks work more-or-less as expected when comparing to other frameworks.

                    I haven't read it yet but https://www.toptal.com/qt/qt-multithreading-c-plus-plus seems like a good additional resource on the topic (for other people who might be stumbling onto the same issue).

                    K Offline
                    K Offline
                    kshegunov
                    Moderators
                    wrote on 5 May 2021, 15:00 last edited by kshegunov 5 May 2021, 15:04
                    #15

                    You have it all here: https://wiki.qt.io/WIP-How_to_create_a_simple_chat_application - single thread, multiple threads, server, client, the works. Courtesy of @VRonin. What you need to do to write this properly is very simple and has nothing to do with threads: you need to make your processing asynchronous. After that it can be in a thread, or not, it doesn't truly matter.

                    Read and abide by the Qt Code of Conduct

                    P 1 Reply Last reply 5 May 2021, 16:01
                    4
                    • K kshegunov
                      5 May 2021, 15:00

                      You have it all here: https://wiki.qt.io/WIP-How_to_create_a_simple_chat_application - single thread, multiple threads, server, client, the works. Courtesy of @VRonin. What you need to do to write this properly is very simple and has nothing to do with threads: you need to make your processing asynchronous. After that it can be in a thread, or not, it doesn't truly matter.

                      P Offline
                      P Offline
                      perry_blueberry
                      wrote on 5 May 2021, 16:01 last edited by
                      #16

                      @kshegunov
                      That seems like a great resource! I will take a look.

                      1 Reply Last reply
                      0

                      16/16

                      5 May 2021, 16:01

                      • Login

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