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. Multithreading
Forum Updated to NodeBB v4.3 + New Features

Multithreading

Scheduled Pinned Locked Moved Unsolved General and Desktop
21 Posts 3 Posters 2.3k 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.
  • jsulmJ jsulm

    @jenya7 said in Multithreading:

    so why create thread?

    If QtConcurrent::run(ConsoleTask ) works you do not have to create a thread explicitly.
    But keep in mind that QtConcurrent::run(ConsoleTask ) creates a thread for you and executes the function there.
    And COMPARSER_ParseCommand will also be excuted in the thread QtConcurrent::run(ConsoleTask ) started.

    J Offline
    J Offline
    jenya7
    wrote on last edited by jenya7
    #6

    @jsulm said in Multithreading:

    @jenya7 said in Multithreading:

    so why create thread?

    If QtConcurrent::run(ConsoleTask ) works you do not have to create a thread explicitly.
    But keep in mind that QtConcurrent::run(ConsoleTask ) creates a thread for you and executes the function there.

    Ah..I see. At list it removes all the burden from me

     QThread main_thread; 
     worker *m_worker = new worker();
     m_worker->moveToThread(&main_thread);
    

    and so on.

    mmm....so COMPARSER_ParseCommand can not be called from the main task?

    jsulmJ J.HilkJ 2 Replies Last reply
    0
    • J jenya7

      @jsulm said in Multithreading:

      @jenya7 said in Multithreading:

      so why create thread?

      If QtConcurrent::run(ConsoleTask ) works you do not have to create a thread explicitly.
      But keep in mind that QtConcurrent::run(ConsoleTask ) creates a thread for you and executes the function there.

      Ah..I see. At list it removes all the burden from me

       QThread main_thread; 
       worker *m_worker = new worker();
       m_worker->moveToThread(&main_thread);
      

      and so on.

      mmm....so COMPARSER_ParseCommand can not be called from the main task?

      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by
      #7

      @jenya7 Yes, QtConcurrent::run() is easy to use and is good for simple use cases.

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

      1 Reply Last reply
      1
      • J jenya7

        @jsulm said in Multithreading:

        @jenya7 said in Multithreading:

        so why create thread?

        If QtConcurrent::run(ConsoleTask ) works you do not have to create a thread explicitly.
        But keep in mind that QtConcurrent::run(ConsoleTask ) creates a thread for you and executes the function there.

        Ah..I see. At list it removes all the burden from me

         QThread main_thread; 
         worker *m_worker = new worker();
         m_worker->moveToThread(&main_thread);
        

        and so on.

        mmm....so COMPARSER_ParseCommand can not be called from the main task?

        J.HilkJ Offline
        J.HilkJ Offline
        J.Hilk
        Moderators
        wrote on last edited by
        #8

        @jenya7 to add to @jsulm
        QtConCurrent is it's own module, and offers quite a lot of possibilities.

        But, since it's a module you'll have to add it to your project file, that comes with all kind of overhead.

        Therefore I suggest for you to look at the (somewhat) new static QThread function of create
        QThread *QThread::create

        in your particular case, it my be even easier than QtConcurrent


        Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


        Q: What's that?
        A: It's blue light.
        Q: What does it do?
        A: It turns blue.

        J 1 Reply Last reply
        2
        • J.HilkJ J.Hilk

          @jenya7 to add to @jsulm
          QtConCurrent is it's own module, and offers quite a lot of possibilities.

          But, since it's a module you'll have to add it to your project file, that comes with all kind of overhead.

          Therefore I suggest for you to look at the (somewhat) new static QThread function of create
          QThread *QThread::create

          in your particular case, it my be even easier than QtConcurrent

          J Offline
          J Offline
          jenya7
          wrote on last edited by
          #9

          @J-Hilk said in Multithreading:

          @jenya7 to add to @jsulm
          QtConCurrent is it's own module, and offers quite a lot of possibilities.

          But, since it's a module you'll have to add it to your project file, that comes with all kind of overhead.

          Therefore I suggest for you to look at the (somewhat) new static QThread function of create
          QThread *QThread::create

          in your particular case, it my be even easier than QtConcurrent

          So what the cons of the module? Application size is bigger? Execution time is slower?

          J.HilkJ 1 Reply Last reply
          0
          • J jenya7

            @J-Hilk said in Multithreading:

            @jenya7 to add to @jsulm
            QtConCurrent is it's own module, and offers quite a lot of possibilities.

            But, since it's a module you'll have to add it to your project file, that comes with all kind of overhead.

            Therefore I suggest for you to look at the (somewhat) new static QThread function of create
            QThread *QThread::create

            in your particular case, it my be even easier than QtConcurrent

            So what the cons of the module? Application size is bigger? Execution time is slower?

            J.HilkJ Offline
            J.HilkJ Offline
            J.Hilk
            Moderators
            wrote on last edited by
            #10

            @jenya7 said in Multithreading:

            So what the cons of the module? Application size is bigger? Execution time is slower?

            Well, with using QtConcurrent, you expand the complexity of your application, and I assume (slightly) longer compile and linker timings.

            Application side and runtime speed sole depend on the implementation of the 2 classes. That I can't say.


            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


            Q: What's that?
            A: It's blue light.
            Q: What does it do?
            A: It turns blue.

            1 Reply Last reply
            2
            • J Offline
              J Offline
              jenya7
              wrote on last edited by
              #11

              With QtConcurrent::run(ConsoleTask ); console application runs some time (5-10 minute) and then shuts down.

              J.HilkJ 1 Reply Last reply
              0
              • J jenya7

                With QtConcurrent::run(ConsoleTask ); console application runs some time (5-10 minute) and then shuts down.

                J.HilkJ Offline
                J.HilkJ Offline
                J.Hilk
                Moderators
                wrote on last edited by
                #12

                @jenya7 sounds like a race condition, can you show as the content of ConsoleTask ?


                Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                Q: What's that?
                A: It's blue light.
                Q: What does it do?
                A: It turns blue.

                J 1 Reply Last reply
                0
                • J.HilkJ J.Hilk

                  @jenya7 sounds like a race condition, can you show as the content of ConsoleTask ?

                  J Offline
                  J Offline
                  jenya7
                  wrote on last edited by jenya7
                  #13

                  @J-Hilk

                  void ConsoleTask (void)
                  {
                          ch_ptr = fgets(cons_str, 256, stdin);
                          if (ch_ptr != nullptr)
                          {
                             trimmed_str =  Trim(cons_str, TRIM_BOTH);
                             COMPARSER_ParseCommand(trimmed_str);
                          }
                  }
                  
                  int main(int argc, char *argv[])
                  {
                     QCoreApplication a(argc, argv);
                  
                     motor_params_file = QCoreApplication::applicationDirPath() + "/motor_params.xml";
                     sys_params_file = QCoreApplication::applicationDirPath() + "/sys_params.xml";
                     script_file = QCoreApplication::applicationDirPath() + "/script.txt";
                  
                     GPIO_Init("/dev/gpiochip0");
                     SPI_Init("/dev/spidev0.0");
                     UART_Init("/dev/serial0");
                     UDP_Init();
                  
                    SCRIPT_Load(script_file.toStdString().c_str());
                  
                    SYS_ParamInit(motor_params_file);
                    SYS_ParamInit(sys_params_file);
                  
                      while (1)
                      {
                         udp_rx_size = UDP_Read(udp_buff_rx, 1024);
                         if (udp_rx_size > 0)
                         {
                             printf("message size = %d \n", udp_rx_size);
                             UDP_HandleRecvPacket(udp_buff_rx);
                         }
                  
                           if(UART_Read())
                           {
                                 COMPARSER_ParseCommand(uart_buff_rx);
                           }
                  
                            QtConcurrent::run(ConsoleTask);
                      }
                  
                  }
                  
                  J.HilkJ 1 Reply Last reply
                  0
                  • J Offline
                    J Offline
                    jenya7
                    wrote on last edited by
                    #14

                    Aaaa...I think it should be like this

                    void ConsoleTask (void)
                    {
                        while (1)  //should be a loop!
                        {
                            ch_ptr = fgets(cons_str, 256, stdin);
                            if (ch_ptr != nullptr)
                            {
                               trimmed_str =  Trim(cons_str, TRIM_BOTH);
                               COMPARSER_ParseCommand(trimmed_str);
                            }
                        }
                    }
                    
                    int main(int argc, char *argv[])
                    {
                             QtConcurrent::run(ConsoleTask);  //start here
                            
                             while(1)
                           {
                           }
                    }
                    
                    
                    1 Reply Last reply
                    0
                    • J jenya7

                      @J-Hilk

                      void ConsoleTask (void)
                      {
                              ch_ptr = fgets(cons_str, 256, stdin);
                              if (ch_ptr != nullptr)
                              {
                                 trimmed_str =  Trim(cons_str, TRIM_BOTH);
                                 COMPARSER_ParseCommand(trimmed_str);
                              }
                      }
                      
                      int main(int argc, char *argv[])
                      {
                         QCoreApplication a(argc, argv);
                      
                         motor_params_file = QCoreApplication::applicationDirPath() + "/motor_params.xml";
                         sys_params_file = QCoreApplication::applicationDirPath() + "/sys_params.xml";
                         script_file = QCoreApplication::applicationDirPath() + "/script.txt";
                      
                         GPIO_Init("/dev/gpiochip0");
                         SPI_Init("/dev/spidev0.0");
                         UART_Init("/dev/serial0");
                         UDP_Init();
                      
                        SCRIPT_Load(script_file.toStdString().c_str());
                      
                        SYS_ParamInit(motor_params_file);
                        SYS_ParamInit(sys_params_file);
                      
                          while (1)
                          {
                             udp_rx_size = UDP_Read(udp_buff_rx, 1024);
                             if (udp_rx_size > 0)
                             {
                                 printf("message size = %d \n", udp_rx_size);
                                 UDP_HandleRecvPacket(udp_buff_rx);
                             }
                      
                               if(UART_Read())
                               {
                                     COMPARSER_ParseCommand(uart_buff_rx);
                               }
                      
                                QtConcurrent::run(ConsoleTask);
                          }
                      
                      }
                      
                      J.HilkJ Offline
                      J.HilkJ Offline
                      J.Hilk
                      Moderators
                      wrote on last edited by
                      #15

                      ok @jenya7

                      that code had to set in for a moment 🙈

                      A couple of things are wrong here.

                      1. One you already noticed. With an infinite while loopat that place, each cycle a new QtConcurrent::run is created and executed, and you'll eventually run out of memory. Likely the cause for your crash.

                      2. Why do you have a QCoreApplication instance, but no event loop? That kind of defeats the purpose and leads to this awkward situation where you have to write your own while loop

                      3. ConsoleTask is clearly using member Variables (without a mutex) if they are used somewhere else than that will eventually cause problems

                      4. With this approach you'll constantly block one of your cpu cores. Is this really what you want to do ? Don't tell me you want to fix that by using some kind of thread sleep function!


                      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                      Q: What's that?
                      A: It's blue light.
                      Q: What does it do?
                      A: It turns blue.

                      J 1 Reply Last reply
                      2
                      • J.HilkJ J.Hilk

                        ok @jenya7

                        that code had to set in for a moment 🙈

                        A couple of things are wrong here.

                        1. One you already noticed. With an infinite while loopat that place, each cycle a new QtConcurrent::run is created and executed, and you'll eventually run out of memory. Likely the cause for your crash.

                        2. Why do you have a QCoreApplication instance, but no event loop? That kind of defeats the purpose and leads to this awkward situation where you have to write your own while loop

                        3. ConsoleTask is clearly using member Variables (without a mutex) if they are used somewhere else than that will eventually cause problems

                        4. With this approach you'll constantly block one of your cpu cores. Is this really what you want to do ? Don't tell me you want to fix that by using some kind of thread sleep function!

                        J Offline
                        J Offline
                        jenya7
                        wrote on last edited by jenya7
                        #16

                        @J-Hilk said in Multithreading:

                        ok @jenya7

                        that code had to set in for a moment 🙈

                        A couple of things are wrong here.

                        1. One you already noticed. With an infinite while loopat that place, each cycle a new QtConcurrent::run is created and executed, and you'll eventually run out of memory. Likely the cause for your crash.

                        2. Why do you have a QCoreApplication instance, but no event loop? That kind of defeats the purpose and leads to this awkward situation where you have to write your own while loop

                        3. ConsoleTask is clearly using member Variables (without a mutex) if they are used somewhere else than that will eventually cause problems

                        4. With this approach you'll constantly block one of your cpu cores. Is this really what you want to do ? Don't tell me you want to fix that by using some kind of thread sleep function!

                        The target is an embedded device (RRi 4). So I run in a constant loop some tasks. besides reading from UDP and UART I analize some script and send commands to slaves.
                        So what is the better option? To open a thread for each task? I don't quite understand where I end up after return a.exec(); in console application, so I did a loop.

                        J.HilkJ 1 Reply Last reply
                        0
                        • J jenya7

                          @J-Hilk said in Multithreading:

                          ok @jenya7

                          that code had to set in for a moment 🙈

                          A couple of things are wrong here.

                          1. One you already noticed. With an infinite while loopat that place, each cycle a new QtConcurrent::run is created and executed, and you'll eventually run out of memory. Likely the cause for your crash.

                          2. Why do you have a QCoreApplication instance, but no event loop? That kind of defeats the purpose and leads to this awkward situation where you have to write your own while loop

                          3. ConsoleTask is clearly using member Variables (without a mutex) if they are used somewhere else than that will eventually cause problems

                          4. With this approach you'll constantly block one of your cpu cores. Is this really what you want to do ? Don't tell me you want to fix that by using some kind of thread sleep function!

                          The target is an embedded device (RRi 4). So I run in a constant loop some tasks. besides reading from UDP and UART I analize some script and send commands to slaves.
                          So what is the better option? To open a thread for each task? I don't quite understand where I end up after return a.exec(); in console application, so I did a loop.

                          J.HilkJ Offline
                          J.HilkJ Offline
                          J.Hilk
                          Moderators
                          wrote on last edited by
                          #17

                          @jenya7

                          That doesn't really sound like extreme time critical operations (analize some script and send commands to slaves) or are event driven, so that you can react to events(e.g new data arrived) directly without waiting in a while loop for it. QUdpSocket and QSerialPort offer these event driven API's. There's no need for a dedicated thread for them.

                          The example you posted would probably work exactly the same with a QTimer, and be more cpu friendly.

                          int main(int argc, char *argv[])
                          {
                             QCoreApplication a(argc, argv);
                          
                             motor_params_file = QCoreApplication::applicationDirPath() + "/motor_params.xml";
                             sys_params_file = QCoreApplication::applicationDirPath() + "/sys_params.xml";
                             script_file = QCoreApplication::applicationDirPath() + "/script.txt";
                          
                             GPIO_Init("/dev/gpiochip0");
                             SPI_Init("/dev/spidev0.0");
                             UART_Init("/dev/serial0");
                             UDP_Init();
                          
                            SCRIPT_Load(script_file.toStdString().c_str());
                          
                            SYS_ParamInit(motor_params_file);
                            SYS_ParamInit(sys_params_file);
                          
                            //... etc
                            QTimer t;
                            QObject::connect(&t, &QTimer::timeout, &t, &ConsoleTask);
                            t.start(20); //20 ms -> 50 times per second
                            
                              return a.exec(); //Important the EventLoop MUST run
                          }
                          

                          Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                          Q: What's that?
                          A: It's blue light.
                          Q: What does it do?
                          A: It turns blue.

                          J 1 Reply Last reply
                          4
                          • J.HilkJ J.Hilk

                            @jenya7

                            That doesn't really sound like extreme time critical operations (analize some script and send commands to slaves) or are event driven, so that you can react to events(e.g new data arrived) directly without waiting in a while loop for it. QUdpSocket and QSerialPort offer these event driven API's. There's no need for a dedicated thread for them.

                            The example you posted would probably work exactly the same with a QTimer, and be more cpu friendly.

                            int main(int argc, char *argv[])
                            {
                               QCoreApplication a(argc, argv);
                            
                               motor_params_file = QCoreApplication::applicationDirPath() + "/motor_params.xml";
                               sys_params_file = QCoreApplication::applicationDirPath() + "/sys_params.xml";
                               script_file = QCoreApplication::applicationDirPath() + "/script.txt";
                            
                               GPIO_Init("/dev/gpiochip0");
                               SPI_Init("/dev/spidev0.0");
                               UART_Init("/dev/serial0");
                               UDP_Init();
                            
                              SCRIPT_Load(script_file.toStdString().c_str());
                            
                              SYS_ParamInit(motor_params_file);
                              SYS_ParamInit(sys_params_file);
                            
                              //... etc
                              QTimer t;
                              QObject::connect(&t, &QTimer::timeout, &t, &ConsoleTask);
                              t.start(20); //20 ms -> 50 times per second
                              
                                return a.exec(); //Important the EventLoop MUST run
                            }
                            
                            J Offline
                            J Offline
                            jenya7
                            wrote on last edited by jenya7
                            #18

                            @J-Hilk said in Multithreading:

                            @jenya7

                            That doesn't really sound like extreme time critical operations (analize some script and send commands to slaves) or are event driven, so that you can react to events(e.g new data arrived) directly without waiting in a while loop for it. QUdpSocket and QSerialPort offer these event driven API's. There's no need for a dedicated thread for them.

                            The example you posted would probably work exactly the same with a QTimer, and be more cpu friendly.

                            Sorry for my slow understanding. Where do I place QUdpSocket , QSerialPort and other tasks - before return a.exec();? They will run constantly? Some task I can connect to a timer. But I have a time critical task - gather info from slaves, analyze it and send command based on the info - it should be really fast.

                            J.HilkJ 1 Reply Last reply
                            0
                            • J Offline
                              J Offline
                              jenya7
                              wrote on last edited by jenya7
                              #19

                              Can I find a non-trivial Console Application example to learn how to do it right?

                              1 Reply Last reply
                              0
                              • J jenya7

                                @J-Hilk said in Multithreading:

                                @jenya7

                                That doesn't really sound like extreme time critical operations (analize some script and send commands to slaves) or are event driven, so that you can react to events(e.g new data arrived) directly without waiting in a while loop for it. QUdpSocket and QSerialPort offer these event driven API's. There's no need for a dedicated thread for them.

                                The example you posted would probably work exactly the same with a QTimer, and be more cpu friendly.

                                Sorry for my slow understanding. Where do I place QUdpSocket , QSerialPort and other tasks - before return a.exec();? They will run constantly? Some task I can connect to a timer. But I have a time critical task - gather info from slaves, analyze it and send command based on the info - it should be really fast.

                                J.HilkJ Offline
                                J.HilkJ Offline
                                J.Hilk
                                Moderators
                                wrote on last edited by
                                #20

                                @jenya7 said in Multithreading:

                                Sorry for my slow understanding. Where do I place QUdpSocket , QSerialPort and other tasks - before return a.exec();? They will run constantly? Some task I can connect to a timer. But I have a time critical task - gather info from slaves, analyze it and send command based on the info - it should be really fast.

                                that is correct, a.exec()will spin the QEventLoop and therefore your program will not exit (return from the function call) until you QApplication::quit is emitted.

                                Can I find non-trivial Console Application example to learn how to do it right?

                                yes of course, the examples Qt offers should actually be enough. They are compile ready and part of your Qt Installation, if you used the online installer.

                                For example:
                                UDP

                                • https://doc.qt.io/qt-5/qtnetwork-broadcastsender-example.html
                                • https://doc.qt.io/qt-5/qtnetwork-broadcastreceiver-example.html
                                • https://doc.qt.io/qt-5/qtnetwork-multicastsender-example.html
                                • https://doc.qt.io/qt-5/qtnetwork-multicastreceiver-example.html

                                SerialPort

                                • https://doc.qt.io/qt-5/qtserialport-examples.html

                                Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                                Q: What's that?
                                A: It's blue light.
                                Q: What does it do?
                                A: It turns blue.

                                1 Reply Last reply
                                2
                                • J Offline
                                  J Offline
                                  jenya7
                                  wrote on last edited by jenya7
                                  #21

                                  Thank you.

                                  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