Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Strange exception.
Qt 6.11 is out! See what's new in the release blog

Strange exception.

Scheduled Pinned Locked Moved Unsolved General and Desktop
18 Posts 4 Posters 2.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.
  • J jenya7

    @VRonin
    I see. Where I should place a QMutex ?

    VRoninV Offline
    VRoninV Offline
    VRonin
    wrote on last edited by
    #5

    @jenya7 said in Strange exception.:

    @VRonin
    I see. Where I should place a QMutex ?

    Depends, where do you define g_queue?

    "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
    ~Napoleon Bonaparte

    On a crusade to banish setIndexWidget() from the holy land of Qt

    J 1 Reply Last reply
    0
    • JonBJ JonB

      @jenya7
      @VRonin types much faster than I can! ;-)

      Completely unrelated comment:

      void PARSER::Run()
      {
          while(1)
      

      Are you aware not to use this "for real"? Have you looked at the load on (some thread/core in) your CPU?

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

      @JonB said in Strange exception.:

      @jenya7
      @VRonin types much faster than I can! ;-)

      Completely unrelated comment:

      void PARSER::Run()
      {
          while(1)
      

      Are you aware not to use this "for real"? Have you looked at the load on (some thread/core in) your CPU?

      How it could be done without while(1)? I want to constantly check if there are some data in queue.

      JonBJ 1 Reply Last reply
      0
      • VRoninV VRonin

        @jenya7 said in Strange exception.:

        @VRonin
        I see. Where I should place a QMutex ?

        Depends, where do you define g_queue?

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

        @VRonin said in Strange exception.:

        @jenya7 said in Strange exception.:

        @VRonin
        I see. Where I should place a QMutex ?

        Depends, where do you define g_queue?

        in udp.cpp
        QQueue<QByteArray> g_queue;

        in udp.h
        extern QQueue<QByteArray> g_queue;

        in parser.cpp
        #include "udp.h"

        1 Reply Last reply
        0
        • VRoninV Offline
          VRoninV Offline
          VRonin
          wrote on last edited by
          #8

          Oh, it's a global.... terrible idea but this is an argument for another time. The mutex will go in the same scope

          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
          ~Napoleon Bonaparte

          On a crusade to banish setIndexWidget() from the holy land of Qt

          J 1 Reply Last reply
          1
          • VRoninV VRonin

            Oh, it's a global.... terrible idea but this is an argument for another time. The mutex will go in the same scope

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

            @VRonin said in Strange exception.:

            Oh, it's a global.... terrible idea but this is an argument for another time. The mutex will go in the same scope
            OK.
            in udp.cpp

            void UDP::ReadyRead()
            {
                QHostAddress sender;
                quint16 senderPort;
                int size;
            
                int count = 0;
            
               g_mutex.lock();
            
                while (socket->hasPendingDatagrams())
                {
                      socket->readDatagram(udp_buffer.data(), udp_buffer.size(),
                                           &sender, &senderPort);
            
                      g_queue.enqueue(udp_buffer);
                      count++;
                }
            
                g_mutex.unlock();
            
                qDebug() << "datagrams: " << count;
            }
            

            and what in void PARSER::Run() ? There is no flag in mutex like g_mutex.isFree() or something.

            1 Reply Last reply
            0
            • J jenya7

              @JonB said in Strange exception.:

              @jenya7
              @VRonin types much faster than I can! ;-)

              Completely unrelated comment:

              void PARSER::Run()
              {
                  while(1)
              

              Are you aware not to use this "for real"? Have you looked at the load on (some thread/core in) your CPU?

              How it could be done without while(1)? I want to constantly check if there are some data in queue.

              JonBJ Online
              JonBJ Online
              JonB
              wrote on last edited by JonB
              #10

              @jenya7 said in Strange exception.:

              How it could be done without while(1)? I want to constantly check if there are some data in queue.

              Your code does:

              void PARSER::Run()
              {
                  while(1)
                  {
                      if (!g_queue.isEmpty())
                      {
              

              That means you are calling g_queue.isEmpty() as fast/many times as your thread/core/CPU can manage it. Even though it's in its own thread, which at least (theoretically/hopefully) means that some time will still be given to your UI/other threads, it will/should basically occupy a complete core running 100% of the time. Good if you want to use your host device as a "heater" for your room, bad if you care about electricity/battery life/wear & tear! And it may interfere with the responsiveness of your other threads.

              You have a couple of possibilities:

              • Make your thread run a Qt event loop (this is the default for QThread), so that you can use QTimer. Only read the queue state every so often in time, to give the thread a chance to sleep. You can achieve this simply using QThread::msleep().

              • Again with a Qt event loop in the thread. Have a signal raised by whatever puts something onto the queue, and the thread has a slot for that which only needs to do:

              while (!g_queue.isEmpty())
                  dequeue_and_process();
              

              and then the slot exits, returning to the thread's event loop.

              In this case the second option is very easy, because you know when you put something new onto the queue: it's the g_queue.enqueue(udp_buffer); in your UDP thread. So just have that emit a signal immediately after queueing a new element.

              J 1 Reply Last reply
              1
              • JonBJ JonB

                @jenya7 said in Strange exception.:

                How it could be done without while(1)? I want to constantly check if there are some data in queue.

                Your code does:

                void PARSER::Run()
                {
                    while(1)
                    {
                        if (!g_queue.isEmpty())
                        {
                

                That means you are calling g_queue.isEmpty() as fast/many times as your thread/core/CPU can manage it. Even though it's in its own thread, which at least (theoretically/hopefully) means that some time will still be given to your UI/other threads, it will/should basically occupy a complete core running 100% of the time. Good if you want to use your host device as a "heater" for your room, bad if you care about electricity/battery life/wear & tear! And it may interfere with the responsiveness of your other threads.

                You have a couple of possibilities:

                • Make your thread run a Qt event loop (this is the default for QThread), so that you can use QTimer. Only read the queue state every so often in time, to give the thread a chance to sleep. You can achieve this simply using QThread::msleep().

                • Again with a Qt event loop in the thread. Have a signal raised by whatever puts something onto the queue, and the thread has a slot for that which only needs to do:

                while (!g_queue.isEmpty())
                    dequeue_and_process();
                

                and then the slot exits, returning to the thread's event loop.

                In this case the second option is very easy, because you know when you put something new onto the queue: it's the g_queue.enqueue(udp_buffer); in your UDP thread. So just have that emit a signal immediately after queueing a new element.

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

                @JonB
                Good points. May in this case I don't need any mutex?

                JonBJ 1 Reply Last reply
                0
                • J jenya7

                  @JonB
                  Good points. May in this case I don't need any mutex?

                  JonBJ Online
                  JonBJ Online
                  JonB
                  wrote on last edited by
                  #12

                  @jenya7 said in Strange exception.:

                  May in this case I don't need any mutex?

                  No, you will still need that. Partly for safety anyway, but mostly even after the UDP thread adds to the queue and emits a signal, you still have a potential race condition between (a) the parser thread pulling the item from the queue as soon as the slot is called versus (b) the UDP thread going round and receiving a new datagram to append to the queue.

                  J 1 Reply Last reply
                  0
                  • JonBJ JonB

                    @jenya7 said in Strange exception.:

                    May in this case I don't need any mutex?

                    No, you will still need that. Partly for safety anyway, but mostly even after the UDP thread adds to the queue and emits a signal, you still have a potential race condition between (a) the parser thread pulling the item from the queue as soon as the slot is called versus (b) the UDP thread going round and receiving a new datagram to append to the queue.

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

                    @JonB
                    How do I do that
                    the first thread

                     g_mutex.lock();
                    //do some stuff
                    g_mutex.unlock();
                    

                    and the second one - how to I test the mutex for unlocked?

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

                      @JonB
                      How do I do that
                      the first thread

                       g_mutex.lock();
                      //do some stuff
                      g_mutex.unlock();
                      

                      and the second one - how to I test the mutex for unlocked?

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

                      @jenya7
                      with https://doc.qt.io/qt-5/qmutex.html#tryLock

                      it will wait, until timeout or until the other thread called unlock


                      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
                      1
                      • J.HilkJ J.Hilk

                        @jenya7
                        with https://doc.qt.io/qt-5/qmutex.html#tryLock

                        it will wait, until timeout or until the other thread called unlock

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

                        @J-Hilk said in Strange exception.:

                        @jenya7
                        with https://doc.qt.io/qt-5/qmutex.html#tryLock

                        it will wait, until timeout or until the other thread called unlock

                        So if in the second thread tryLock returns true - should I unlock immediately after g_queue.dequeue(); ?

                        JonBJ 1 Reply Last reply
                        0
                        • J jenya7

                          @JonB
                          How do I do that
                          the first thread

                           g_mutex.lock();
                          //do some stuff
                          g_mutex.unlock();
                          

                          and the second one - how to I test the mutex for unlocked?

                          JonBJ Online
                          JonBJ Online
                          JonB
                          wrote on last edited by
                          #16

                          @jenya7
                          In this particular case your parser thread could actually do an unconditional g_mutex.lock(); too. That would block if the UDP thread has already taken the lock. But because you have "nothing else to do" in your thread it doesn't matter anyway.

                          However, you may prefer to use @J-Hilk's suggestion of tryLock(), as it may sound more "intuitive". There are other cases --- where your thread does have other things to do if a lock cannot be taken immediately --- where you would require tryLock(), so it may be a habit you want to get into.

                          1 Reply Last reply
                          0
                          • J jenya7

                            @J-Hilk said in Strange exception.:

                            @jenya7
                            with https://doc.qt.io/qt-5/qmutex.html#tryLock

                            it will wait, until timeout or until the other thread called unlock

                            So if in the second thread tryLock returns true - should I unlock immediately after g_queue.dequeue(); ?

                            JonBJ Online
                            JonBJ Online
                            JonB
                            wrote on last edited by
                            #17

                            @jenya7 said in Strange exception.:

                            So if in the second thread tryLock returns true - should I unlock immediately after g_queue.dequeue(); ?

                            Yep :) And don't forget to do so immediately after dequeuing, not after you have processed the element.

                            J 1 Reply Last reply
                            0
                            • JonBJ JonB

                              @jenya7 said in Strange exception.:

                              So if in the second thread tryLock returns true - should I unlock immediately after g_queue.dequeue(); ?

                              Yep :) And don't forget to do so immediately after dequeuing, not after you have processed the element.

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

                              Thank you guys. With mutex it works good. Sometimes I get broken datagrams but it seems like I overload the network card. For 27500 packets I get 11 broken.

                              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
                              • Unsolved