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. GUI freezes even with multithreading

GUI freezes even with multithreading

Scheduled Pinned Locked Moved Unsolved General and Desktop
@dheerendraqt 5.5qthreadqserialportqnetwork
17 Posts 3 Posters 16.5k 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.
  • D Offline
    D Offline
    dev_512
    wrote on last edited by
    #1

    QT application GUI on Ubuntu 16.04 freezes.
    What we are using -
    Intel Celeron dual core 1.6GHz, RAM 2GB, 128gb SSD.

    We have used two smart cameras (ethernet).
    We have used QNetworkmanager to grab images from the cameras. We have used QSocket for communicating with the Cameras (socket server). We are updating data (not images, only camera result data, very small) on MySQL server every 500ms. We have also used serial communication to communicate with a micro controller at 115200 baud rate. We use QSerialport for this. Frequency of serial data varies.

    The problem we used to face is that after prolonged use, sometimes, the GUI would freeze (screen would turn black and white, i.e application not responding). After waiting for some time, the GUI would recover and start running normally. This would happen randomly and not periodically. Sometimes the GUI would hang everyday, but sometimes, it would not hang for a week or two. We have checked that there are no memory leaks, no over heating, no noise. We then realised that the data coming in was a lot to process on the main thread. So to avoid this, we used Qthread. Now, we have separate threads for QNetworkmanager, Serial communication & Database writing. After this, the screen does not go black and white (not responding), but for some seconds, the screen stops functioning (no buttons can be pressed or no screen transition takes place). It looks like a long lag in the GUI operations. After multithreading, the application not responding problem has stopped but the screen still freezes for sometime. Now, sometimes, the application hangs even after starting it (at user login).

    We thought that since each thread executes continuously and processes incoming data and passes it to the main thread at a very high frequency, the application becomes slow and hangs. So we added sleep delays of around 500ms to each thread. Unfortunately, even after doing this, the application froze for 45 seconds. The application started running properly after that. The application froze when a button was pressed that closes the login form and goes to the run form (at this time, all threads start). Here we think that the application took some time to start all threads. We would be grateful to receive help on this issue. thank you.
    For your reference, I've attached a video link to show the freeze problem. Please watch the video till the end to see how the GUI recovers from the freeze.

    Video link click here

    Constructor in main thread -

    /**************************START Of Constructor*****************************************/
    frm_run::frm_run(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::frm_run)
    {
        ui->setupUi(this);
    
        try
        {
        this->setWindowFlags(Qt::FramelessWindowHint);  // To remove screen Title bar
    
        ThreadMysql =new thread_mysql;          //Thread for mysql data update
        ThreadMysql->start();
    
        ThreadSerial = new thread_serial;       //thread for serial recive data parce
        ThreadSerial->start();
    
        ThreadBaumer = new thread_baumer;       //Thread for Image grab from Web
        ThreadBaumer->start();
    
    
    
    
        Login_name = dlg_login::current_user;
        Login_level = dlg_login::Current_level;
        qDebug()<<"level"<<Login_level;
    
    
        /********************Keyboard Connection with LineEdit**********/
    
    
        lineEditkeyboard = new Keyboard;
        connect(ui->txt_light ,SIGNAL(selectionChanged()),this,SLOT(run_keyboard_lineEdit()));
        connect(ui->txt_shift_image ,SIGNAL(selectionChanged()),this,SLOT(run_keyboard_lineEdit()));
        connect(ui->txt_JobNumber ,SIGNAL(selectionChanged()),this,SLOT(run_keyboard_lineEdit()));
        connect(ui->txt_ProductID ,SIGNAL(selectionChanged()),this,SLOT(run_keyboard_lineEdit()));
        connect(ui->txt_Tollerence ,SIGNAL(selectionChanged()),this,SLOT(run_keyboard_lineEdit()));
        connect(ui->txt_Area_Threshold ,SIGNAL(selectionChanged()),this,SLOT(run_keyboard_lineEdit()));
    
        global::JobStatus = 0;
        QSqlQuery QRY;
        QString Query="select job_status,work_ticket_no,product_id from JOB_DETAILS  WHERE job_status = '1' OR job_status = '2'";
    
        if(QRY.exec(Query))
        {
            while(QRY.next())
            {
                global::JobStatus = QRY.value(QRY.record().indexOf("job_status")).toUInt();
                global::WorktktNo = QRY.value(QRY.record().indexOf("work_ticket_no")).toString();
                ProductID = QRY.value(QRY.record().indexOf("product_id")).toString();
            }
        }
    
    
    
    
    
        Query="select * from MACHINE_SETTING WHERE id = 1 ";
    
        if(QRY.exec(Query))
        {
            while(QRY.next())
            {
    
                multiplier = (QRY.value(QRY.record().indexOf("multiplier")).toDouble());
                EjectionStatus = (QRY.value(QRY.record().indexOf("ejection_status")).toUInt());
                MaxConsBad = (QRY.value(QRY.record().indexOf("max_cons_bad")).toUInt());
                Ejector_Distance = (QRY.value(QRY.record().indexOf("ejector_distance")).toUInt());
    
                FeederToCam1Dist = (QRY.value(QRY.record().indexOf("feeder_to_cam1_dist")).toUInt());
                FeederToCam2Dist = (QRY.value(QRY.record().indexOf("feeder_to_cam2_dist")).toUInt());
    
                Exposure = (QRY.value(QRY.record().indexOf("exposure")).toUInt());
                Cam2Exposure = (QRY.value(QRY.record().indexOf("cam2_exposure")).toUInt());
    
                global::Cam1IP = QRY.value(QRY.record().indexOf("cam1_ip")).toString();
                global::Cam2IP = QRY.value(QRY.record().indexOf("cam2_ip")).toString();
    
                Pattern_Theshold = (QRY.value(QRY.record().indexOf("pattern_theshold")).toDouble());
                Area_enable = (QRY.value(QRY.record().indexOf("area_enable")).toUInt());
    
                flag_TopCamEnable = (QRY.value(QRY.record().indexOf("top_enable")).toInt());
                flag_BtmCamEnable = (QRY.value(QRY.record().indexOf("bottom_enable")).toInt());
            }
        }
    
        qDebug()<<"top_enable"<<flag_TopCamEnable<<flag_BtmCamEnable;
    
        TopCam_S = new Socket_Class;
        BtmCam_S = new Socket_Class;
    
    
        File_Class::send_log("Run Form Start");
    
    
    
    
        connect(ThreadSerial,SIGNAL(rec_com_data()),this,SLOT(show_serial_data()));
    
         connect(ThreadBaumer,SIGNAL(geting_image_cam()),this,SLOT(GetImage()));
    
    
    
    
    
        connect(TopCam_S,&Socket_Class::client_status,this,&frm_run::get_top_status);
        connect(TopCam_S,&Socket_Class::client_data,this,&frm_run::get_top_data);
    
    
        connect(BtmCam_S,&Socket_Class::client_status,this,&frm_run::get_btm_status);
        connect(BtmCam_S,&Socket_Class::client_data,this,&frm_run::get_btm_data);
    
        connect(ThreadBaumer,SIGNAL(put_image_cam1()),this,SLOT(get_top_web()));
        connect(ThreadBaumer,SIGNAL(put_image_cam2()),this,SLOT(get_btm_web()));
    
        connect(ui->Image_Box,SIGNAL(Mouse_Pos()),this,SLOT(Mouse_current_pos()));
        connect(ui->Image_Box,SIGNAL(Mouse_Pressed()),this,SLOT(Mouse_Pressed()));
        connect(ui->Image_Box,SIGNAL(Mouse_Left()),this,SLOT(Mouse_Left()));
    
    
        if(flag_TopCamEnable == 1)
        {
            Cam1Sel = 1;
        }
        else
        {
            Cam1Sel = 0;
        }
    
        if(flag_BtmCamEnable == 1)
        {
            Cam2Sel = 1;
        }
        else
        {
            Cam2Sel = 0;
        }
    
    
    
    
        LoadDatabase();     // Load Parameters from Database
        if((global::JobStatus == 1)||(global::JobStatus == 2))
        {
    
            send_data();            // Send parameter to microcontroller by Serial Port
        }
        ui->txt_shift_image->setReadOnly(true);
        ui->txt_light->setReadOnly(true);
        ui->txt_Tollerence->setReadOnly(true);
        if(Cam1Sel == 1)
        {
            TopCam_S->Cam_Connect(global::Cam1IP);      // Connect to Socket  Server
        }
        if(Cam2Sel == 1)
        {
            BtmCam_S->Cam_Connect(global::Cam2IP);  // Connect to Socket  Server
        }
    
    
        ui->Txt_MachineMode->setVisible(false);
        ui->txt_User->setEnabled(false);
        ui->txt_UserLevel->setEnabled(false);
        //ui->btn_Logout->setEnabled(false);
       // ui->btn_Finish->setEnabled(false);
    
        if(global::JobStatus != 0)
        {
            ui->txt_JobNumber->setEnabled(false);
            ui->chk_cam1->setEnabled(false);
            ui->chk_cam2->setEnabled(false);
            ui->btn_List->setVisible(false);
            if(global::JobStatus == 1)
            {
    
                #ifdef ADVANCE
                ui->btn_CodeType->setEnabled(true);
                #else
                 ui->btn_CodeType->setEnabled(false);
                #endif
    
            }
            else
            {
                ui->btn_CodeType->setEnabled(false);
            }
            ui->btn_ROI->setEnabled(true);
            ui->btn_En_ROI->setEnabled(true);
    
        }
        else
        {
    
            ui->btn_CodeType->setEnabled(false);
            ui->btn_ROI->setEnabled(false);
            ui->btn_En_ROI->setEnabled(false);
        }
    
    
        ui->txt_ProductID->setEnabled(false);
    
    
        if((global::JobStatus == 1)||(global::JobStatus == 2))
        {
            send_tcp_cam_Parameter();       // Send Socket Command to two Socket Server
        }
    
        qDebug()<<"End of funtion" <<Cam1Sel<<" "<<Cam2Sel;
    
    
        }
        catch(...)
        {
            //send_log("Mainwindow",1);
        }
    }
    
    
    /**************************END Of Constructor*****************************************/
    -- 
    

    Our Thread run looks like this -

    void function::run()
     {
    QMutex mutex;
    
        while(1)
        {
            mutex.lock();
    
            if(this->Stop)
            {
                break;
            }
    	// function processing
             mutex.unlock();       
            QThread::msleep(500);
        }
    }
    
    
    

    Would really appreciate help.

    @dheerendra

    J.HilkJ 1 Reply Last reply
    0
    • D dev_512

      QT application GUI on Ubuntu 16.04 freezes.
      What we are using -
      Intel Celeron dual core 1.6GHz, RAM 2GB, 128gb SSD.

      We have used two smart cameras (ethernet).
      We have used QNetworkmanager to grab images from the cameras. We have used QSocket for communicating with the Cameras (socket server). We are updating data (not images, only camera result data, very small) on MySQL server every 500ms. We have also used serial communication to communicate with a micro controller at 115200 baud rate. We use QSerialport for this. Frequency of serial data varies.

      The problem we used to face is that after prolonged use, sometimes, the GUI would freeze (screen would turn black and white, i.e application not responding). After waiting for some time, the GUI would recover and start running normally. This would happen randomly and not periodically. Sometimes the GUI would hang everyday, but sometimes, it would not hang for a week or two. We have checked that there are no memory leaks, no over heating, no noise. We then realised that the data coming in was a lot to process on the main thread. So to avoid this, we used Qthread. Now, we have separate threads for QNetworkmanager, Serial communication & Database writing. After this, the screen does not go black and white (not responding), but for some seconds, the screen stops functioning (no buttons can be pressed or no screen transition takes place). It looks like a long lag in the GUI operations. After multithreading, the application not responding problem has stopped but the screen still freezes for sometime. Now, sometimes, the application hangs even after starting it (at user login).

      We thought that since each thread executes continuously and processes incoming data and passes it to the main thread at a very high frequency, the application becomes slow and hangs. So we added sleep delays of around 500ms to each thread. Unfortunately, even after doing this, the application froze for 45 seconds. The application started running properly after that. The application froze when a button was pressed that closes the login form and goes to the run form (at this time, all threads start). Here we think that the application took some time to start all threads. We would be grateful to receive help on this issue. thank you.
      For your reference, I've attached a video link to show the freeze problem. Please watch the video till the end to see how the GUI recovers from the freeze.

      Video link click here

      Constructor in main thread -

      /**************************START Of Constructor*****************************************/
      frm_run::frm_run(QWidget *parent) :
          QMainWindow(parent),
          ui(new Ui::frm_run)
      {
          ui->setupUi(this);
      
          try
          {
          this->setWindowFlags(Qt::FramelessWindowHint);  // To remove screen Title bar
      
          ThreadMysql =new thread_mysql;          //Thread for mysql data update
          ThreadMysql->start();
      
          ThreadSerial = new thread_serial;       //thread for serial recive data parce
          ThreadSerial->start();
      
          ThreadBaumer = new thread_baumer;       //Thread for Image grab from Web
          ThreadBaumer->start();
      
      
      
      
          Login_name = dlg_login::current_user;
          Login_level = dlg_login::Current_level;
          qDebug()<<"level"<<Login_level;
      
      
          /********************Keyboard Connection with LineEdit**********/
      
      
          lineEditkeyboard = new Keyboard;
          connect(ui->txt_light ,SIGNAL(selectionChanged()),this,SLOT(run_keyboard_lineEdit()));
          connect(ui->txt_shift_image ,SIGNAL(selectionChanged()),this,SLOT(run_keyboard_lineEdit()));
          connect(ui->txt_JobNumber ,SIGNAL(selectionChanged()),this,SLOT(run_keyboard_lineEdit()));
          connect(ui->txt_ProductID ,SIGNAL(selectionChanged()),this,SLOT(run_keyboard_lineEdit()));
          connect(ui->txt_Tollerence ,SIGNAL(selectionChanged()),this,SLOT(run_keyboard_lineEdit()));
          connect(ui->txt_Area_Threshold ,SIGNAL(selectionChanged()),this,SLOT(run_keyboard_lineEdit()));
      
          global::JobStatus = 0;
          QSqlQuery QRY;
          QString Query="select job_status,work_ticket_no,product_id from JOB_DETAILS  WHERE job_status = '1' OR job_status = '2'";
      
          if(QRY.exec(Query))
          {
              while(QRY.next())
              {
                  global::JobStatus = QRY.value(QRY.record().indexOf("job_status")).toUInt();
                  global::WorktktNo = QRY.value(QRY.record().indexOf("work_ticket_no")).toString();
                  ProductID = QRY.value(QRY.record().indexOf("product_id")).toString();
              }
          }
      
      
      
      
      
          Query="select * from MACHINE_SETTING WHERE id = 1 ";
      
          if(QRY.exec(Query))
          {
              while(QRY.next())
              {
      
                  multiplier = (QRY.value(QRY.record().indexOf("multiplier")).toDouble());
                  EjectionStatus = (QRY.value(QRY.record().indexOf("ejection_status")).toUInt());
                  MaxConsBad = (QRY.value(QRY.record().indexOf("max_cons_bad")).toUInt());
                  Ejector_Distance = (QRY.value(QRY.record().indexOf("ejector_distance")).toUInt());
      
                  FeederToCam1Dist = (QRY.value(QRY.record().indexOf("feeder_to_cam1_dist")).toUInt());
                  FeederToCam2Dist = (QRY.value(QRY.record().indexOf("feeder_to_cam2_dist")).toUInt());
      
                  Exposure = (QRY.value(QRY.record().indexOf("exposure")).toUInt());
                  Cam2Exposure = (QRY.value(QRY.record().indexOf("cam2_exposure")).toUInt());
      
                  global::Cam1IP = QRY.value(QRY.record().indexOf("cam1_ip")).toString();
                  global::Cam2IP = QRY.value(QRY.record().indexOf("cam2_ip")).toString();
      
                  Pattern_Theshold = (QRY.value(QRY.record().indexOf("pattern_theshold")).toDouble());
                  Area_enable = (QRY.value(QRY.record().indexOf("area_enable")).toUInt());
      
                  flag_TopCamEnable = (QRY.value(QRY.record().indexOf("top_enable")).toInt());
                  flag_BtmCamEnable = (QRY.value(QRY.record().indexOf("bottom_enable")).toInt());
              }
          }
      
          qDebug()<<"top_enable"<<flag_TopCamEnable<<flag_BtmCamEnable;
      
          TopCam_S = new Socket_Class;
          BtmCam_S = new Socket_Class;
      
      
          File_Class::send_log("Run Form Start");
      
      
      
      
          connect(ThreadSerial,SIGNAL(rec_com_data()),this,SLOT(show_serial_data()));
      
           connect(ThreadBaumer,SIGNAL(geting_image_cam()),this,SLOT(GetImage()));
      
      
      
      
      
          connect(TopCam_S,&Socket_Class::client_status,this,&frm_run::get_top_status);
          connect(TopCam_S,&Socket_Class::client_data,this,&frm_run::get_top_data);
      
      
          connect(BtmCam_S,&Socket_Class::client_status,this,&frm_run::get_btm_status);
          connect(BtmCam_S,&Socket_Class::client_data,this,&frm_run::get_btm_data);
      
          connect(ThreadBaumer,SIGNAL(put_image_cam1()),this,SLOT(get_top_web()));
          connect(ThreadBaumer,SIGNAL(put_image_cam2()),this,SLOT(get_btm_web()));
      
          connect(ui->Image_Box,SIGNAL(Mouse_Pos()),this,SLOT(Mouse_current_pos()));
          connect(ui->Image_Box,SIGNAL(Mouse_Pressed()),this,SLOT(Mouse_Pressed()));
          connect(ui->Image_Box,SIGNAL(Mouse_Left()),this,SLOT(Mouse_Left()));
      
      
          if(flag_TopCamEnable == 1)
          {
              Cam1Sel = 1;
          }
          else
          {
              Cam1Sel = 0;
          }
      
          if(flag_BtmCamEnable == 1)
          {
              Cam2Sel = 1;
          }
          else
          {
              Cam2Sel = 0;
          }
      
      
      
      
          LoadDatabase();     // Load Parameters from Database
          if((global::JobStatus == 1)||(global::JobStatus == 2))
          {
      
              send_data();            // Send parameter to microcontroller by Serial Port
          }
          ui->txt_shift_image->setReadOnly(true);
          ui->txt_light->setReadOnly(true);
          ui->txt_Tollerence->setReadOnly(true);
          if(Cam1Sel == 1)
          {
              TopCam_S->Cam_Connect(global::Cam1IP);      // Connect to Socket  Server
          }
          if(Cam2Sel == 1)
          {
              BtmCam_S->Cam_Connect(global::Cam2IP);  // Connect to Socket  Server
          }
      
      
          ui->Txt_MachineMode->setVisible(false);
          ui->txt_User->setEnabled(false);
          ui->txt_UserLevel->setEnabled(false);
          //ui->btn_Logout->setEnabled(false);
         // ui->btn_Finish->setEnabled(false);
      
          if(global::JobStatus != 0)
          {
              ui->txt_JobNumber->setEnabled(false);
              ui->chk_cam1->setEnabled(false);
              ui->chk_cam2->setEnabled(false);
              ui->btn_List->setVisible(false);
              if(global::JobStatus == 1)
              {
      
                  #ifdef ADVANCE
                  ui->btn_CodeType->setEnabled(true);
                  #else
                   ui->btn_CodeType->setEnabled(false);
                  #endif
      
              }
              else
              {
                  ui->btn_CodeType->setEnabled(false);
              }
              ui->btn_ROI->setEnabled(true);
              ui->btn_En_ROI->setEnabled(true);
      
          }
          else
          {
      
              ui->btn_CodeType->setEnabled(false);
              ui->btn_ROI->setEnabled(false);
              ui->btn_En_ROI->setEnabled(false);
          }
      
      
          ui->txt_ProductID->setEnabled(false);
      
      
          if((global::JobStatus == 1)||(global::JobStatus == 2))
          {
              send_tcp_cam_Parameter();       // Send Socket Command to two Socket Server
          }
      
          qDebug()<<"End of funtion" <<Cam1Sel<<" "<<Cam2Sel;
      
      
          }
          catch(...)
          {
              //send_log("Mainwindow",1);
          }
      }
      
      
      /**************************END Of Constructor*****************************************/
      -- 
      

      Our Thread run looks like this -

      void function::run()
       {
      QMutex mutex;
      
          while(1)
          {
              mutex.lock();
      
              if(this->Stop)
              {
                  break;
              }
      	// function processing
               mutex.unlock();       
              QThread::msleep(500);
          }
      }
      
      
      

      Would really appreciate help.

      @dheerendra

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

      @dev_512
      you're running 4 threads, 3 of them in a while true loop and asking yourself why the OS has trouble managing the tasks, do you at least have 4 cores - real ones not hyper threading stuff?

      I would suggest at the very least, put the processing threads into one and the Gui into the other, and read through this

      https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/
      It will go a long way ;-)

      and for heavens sake do not use QThread::sleep, it will cause more problems than it will fix


      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.

      D 1 Reply Last reply
      6
      • dheerendraD Offline
        dheerendraD Offline
        dheerendra
        Qt Champions 2022
        wrote on last edited by
        #3

        Apart from what @J-Hilk said, first your MainWindow constructor is very heavy.

        Your UI freezes means that GUI thread is busy. Why it is busy ? We need to find out.

        Your MainWindows constructor is heavily loaded. It is following things.

        1. Starts thread
        2. Makes db query
        3. Connects with Camera
        4. Loading DB

        All this could be taking around 45 seconds & i'm not surprised. Just to trouble shoot the issue, start Simple UI creation. Then start adding one-by-one functionality. This should give you the exact reason why UI freezes.

        Dheerendra
        @Community Service
        Certified Qt Specialist
        http://www.pthinks.com

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

          @dev_512
          you're running 4 threads, 3 of them in a while true loop and asking yourself why the OS has trouble managing the tasks, do you at least have 4 cores - real ones not hyper threading stuff?

          I would suggest at the very least, put the processing threads into one and the Gui into the other, and read through this

          https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/
          It will go a long way ;-)

          and for heavens sake do not use QThread::sleep, it will cause more problems than it will fix

          D Offline
          D Offline
          dev_512
          wrote on last edited by
          #4

          @J.Hil Thank you is much for your reply. I wanted to know how to avoid using sleep. Without using sleep, the threads will run very quickly compared to the main thread and emit a lot of data very rapidly. How to avoid sleep then? The GUI starts lagging and becomes unresponsive. Now that we are using sleep, we haven't noticed that problem yet.

          J.HilkJ 1 Reply Last reply
          0
          • D dev_512

            @J.Hil Thank you is much for your reply. I wanted to know how to avoid using sleep. Without using sleep, the threads will run very quickly compared to the main thread and emit a lot of data very rapidly. How to avoid sleep then? The GUI starts lagging and becomes unresponsive. Now that we are using sleep, we haven't noticed that problem yet.

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

            @dev_512
            that really depends on what you're actully doing inside the run function.
            I would recommend reading through the block post I linked earlier, it's an old one but still valid. Since then the QThread-docu actually has a example of the worker approach.

            If you really have to stick with what you allready have I would suggest a QTimer.

            • remove the while loop
            • move the stuff inside the loop to its own function
            • create a QTimer inside run, set the intvall to 500
            • connect the timeout signal to the function
              • The function will be executed inside the calling thread
            • start the timer
            • call exec() at the end of 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.

            D 2 Replies Last reply
            3
            • J.HilkJ J.Hilk

              @dev_512
              that really depends on what you're actully doing inside the run function.
              I would recommend reading through the block post I linked earlier, it's an old one but still valid. Since then the QThread-docu actually has a example of the worker approach.

              If you really have to stick with what you allready have I would suggest a QTimer.

              • remove the while loop
              • move the stuff inside the loop to its own function
              • create a QTimer inside run, set the intvall to 500
              • connect the timeout signal to the function
                • The function will be executed inside the calling thread
              • start the timer
              • call exec() at the end of run
              D Offline
              D Offline
              dev_512
              wrote on last edited by
              #6

              @J.Hilk Okay thank you, I am removing sleep delays, removing all threads and just making one GUI thread and another thread that will do all continuous functions such as serial, socket, QNetwork, etc. Thank you very much. Will let you know how it works out.

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

                @dev_512
                that really depends on what you're actully doing inside the run function.
                I would recommend reading through the block post I linked earlier, it's an old one but still valid. Since then the QThread-docu actually has a example of the worker approach.

                If you really have to stick with what you allready have I would suggest a QTimer.

                • remove the while loop
                • move the stuff inside the loop to its own function
                • create a QTimer inside run, set the intvall to 500
                • connect the timeout signal to the function
                  • The function will be executed inside the calling thread
                • start the timer
                • call exec() at the end of run
                D Offline
                D Offline
                dev_512
                wrote on last edited by
                #7

                @J.Hilk hi, I have now formed only 1 thread apart from the main thread. In this thread, I have performed all the continuous functions and I have used QTimer instead of sleep now. I wanted to know if I have to assign a core of the processor to the thread. I don’t know if that needs to be done. Thank you.

                1 Reply Last reply
                0
                • dheerendraD Offline
                  dheerendraD Offline
                  dheerendra
                  Qt Champions 2022
                  wrote on last edited by dheerendra
                  #8

                  You don't have to. It is not required. You can't directly unless you write some platform dependent code. Are you seeing any issue ?

                  Dheerendra
                  @Community Service
                  Certified Qt Specialist
                  http://www.pthinks.com

                  D 1 Reply Last reply
                  2
                  • dheerendraD dheerendra

                    You don't have to. It is not required. You can't directly unless you write some platform dependent code. Are you seeing any issue ?

                    D Offline
                    D Offline
                    dev_512
                    wrote on last edited by
                    #9

                    @dheerendra no issues so far. Will update. Thank you.

                    1 Reply Last reply
                    0
                    • D Offline
                      D Offline
                      dev_512
                      wrote on last edited by
                      #10

                      @J.Hilk @dheerendra Hi, as you had suggested, we stopped using 4 threads and now are using just the main thread and another thread. We do all the continuous data handling functions in the other thread while GUI runs in the main thread. The system worked fine for 20-22 days (daily use). The system is used (in running state) almost 24*7 with lunch and tea breaks. After 20-22 days, the application became unresponsive (black and white screen in Ubuntu). Could the processor be the issue? It is a 1.6GHz dual core processor. Please help.

                      1 Reply Last reply
                      0
                      • dheerendraD Offline
                        dheerendraD Offline
                        dheerendra
                        Qt Champions 2022
                        wrote on last edited by
                        #11

                        Just see whether process is still running ? Just check it is a issue of memory ? Are there any memory leaks in your program ?

                        Dheerendra
                        @Community Service
                        Certified Qt Specialist
                        http://www.pthinks.com

                        D 1 Reply Last reply
                        0
                        • dheerendraD dheerendra

                          Just see whether process is still running ? Just check it is a issue of memory ? Are there any memory leaks in your program ?

                          D Offline
                          D Offline
                          dev_512
                          wrote on last edited by
                          #12

                          @dheerendra No Sir, we have performed checks. no memory leaks. The free RAM memory stays constant even after an entire day. So we take and process data in the worker thread. After the processing, we pass the data to the main GUI thread. In case the worker thread hangs due to some reason, is it possible that the main thread will hang too? The worker thread does all the work while the main thread only receives and displays the result.

                          1 Reply Last reply
                          0
                          • dheerendraD Offline
                            dheerendraD Offline
                            dheerendra
                            Qt Champions 2022
                            wrote on last edited by
                            #13

                            No main will not hang because of worker is hung. This can only happen if any dead lock arises. If you are using signal/slots without Qt::DirectConnection, it should not hang.

                            Now only way is to troubleshoot what is worker thread doing & why it is hung.

                            Dheerendra
                            @Community Service
                            Certified Qt Specialist
                            http://www.pthinks.com

                            1 Reply Last reply
                            0
                            • D Offline
                              D Offline
                              dev_512
                              wrote on last edited by
                              #14

                              @dheerendra So just to check, we put an infinite while loop in the worker thread and started the system. The worker thread after processing data from serial communication and QImage function, generates signals and sends it to the main GUI thread. The Main thread only takes action after receiving these signals and displays the result on screen. Now when we added a while loop (infinite count) to the worker thread, the worker thread got busy performing that and stopped other tasks. Due to this, the worker thread stopped generating signals and hence, the GUI didn't display anything. However, the GUI did not freeze at all. The micro controller was sending data to the PC but the worker thread did not process anything since it was stuck in the while loop. We thought that this would freeze the main thread but the main thread (GUI) was completely responsive. Due to this, we think that something in the main thread hangs.
                              If the worker thread is stuck, the GUI thread does not become unresponsive. If we add the infinite counting while loop to the main thread, the GUI freezes immediately (not responding).
                              I am attaching the main thread so you can observe and suggest any changes. Please help. Thank you.

                              #include "mainwindow.h"
                              #include "ui_mainwindow.h"
                              #include"serialcom.h"
                              #include <QThread>
                              #include <QDebug>
                              #include "my_label.h"
                              #include "baumer_class.h"
                              #include "file_class.h"
                              #include "mysql_class.h"
                              #include "global.h"
                              
                              #include <QtSql>
                              #include <QtSql/QSqlDatabase>
                              #include <QtSql/QSqlQuery>
                              
                              #include "frm_run.h"
                              
                              
                              
                              MainWindow::MainWindow(QWidget *parent) :
                                  QMainWindow(parent),
                                  ui(new Ui::MainWindow)
                              {
                                  ui->setupUi(this);
                                  this->setWindowFlags(Qt::FramelessWindowHint);
                              
                                  //SerialCom::com_connect();
                              
                                  SerialCom::send_command(2,1);
                                  thread()->msleep(5);
                              
                                  this->updateGeometry();
                                  #ifdef ADVANCE
                              
                                     ui->lbl_Version->setText(QString(global::VERSION + ".a"));
                                  #else
                                    // ui->lbl_Version->setText("v 1.2.7.b");
                                     ui->lbl_Version->setText(QString(global::VERSION + ".b"));
                                  #endif;
                              
                              
                                    JobStatus = 0;
                                    QSqlQuery QRY;
                                    QString Query="select job_status,work_ticket_no,product_id from JOB_DETAILS  WHERE job_status = '1' OR job_status = '2'";
                              
                                    if(QRY.exec(Query))
                                    {
                                        while(QRY.next())
                                        {
                                            JobStatus = QRY.value(QRY.record().indexOf("job_status")).toUInt();
                                            WorktktNo = QRY.value(QRY.record().indexOf("work_ticket_no")).toString();
                                            ProductID = QRY.value(QRY.record().indexOf("product_id")).toString();
                                        }
                                    }
                              
                              
                                    Query="select * from MACHINE_SETTING WHERE id = 1 ";
                              
                                    if(QRY.exec(Query))
                                    {
                                        while(QRY.next())
                                        {
                                            flag_TopCamEnable = (QRY.value(QRY.record().indexOf("top_enable")).toInt());
                                            flag_BtmCamEnable = (QRY.value(QRY.record().indexOf("bottom_enable")).toInt());
                                        }
                                    }
                              
                              
                                    update_timer = new QTimer;
                                    check_count = 0;
                                    connect(update_timer,SIGNAL(timeout()),this,SLOT(update_data()));
                              
                                    if((flag_TopCamEnable == 1)&&(global::Top_SID_Connect ==false))
                                    {
                              
                                            QProcess process_1;
                                            process_1.startDetached("/bin/sh", QStringList()<< global::PATH_GET_SID_TOP);
                              
                                            update_timer->start(15000);
                                            flag_top_connect = true;
                                            flag_btm_connect = false;
                                            ui->lbl_status->setText("Top Camera Connecting...");
                              
                                    }
                                    else if(global::Btm_SID_Connect == false)
                                    {
                                        QProcess process;
                                        process.startDetached("/bin/sh", QStringList()<< global::PATH_GET_SID_BTM);
                              
                                        update_timer->start(15000);
                                        flag_top_connect = false;
                                        flag_btm_connect = true;
                                        ui->lbl_status->setText("Bottom Camera Connecting wait...");
                                    }
                              
                                    if(flag_TopCamEnable != 1 )
                                    {
                                         global::Top_SID_Connect = true;
                                    }
                              
                                    if(flag_BtmCamEnable != 1)
                                    {
                                        global::Btm_SID_Connect = true;
                                    }
                              
                              
                                     #ifdef PC
                                    ui->btn_login->setEnabled(true);
                                     #else
                                        if((global::Top_SID_Connect == true) &&(global::Btm_SID_Connect == true))
                                        {
                                            ui->btn_login->setEnabled(true);
                                        }
                                        else
                                        {
                                        ui->btn_login->setText("Wait...");
                                         ui->btn_login->setEnabled(false);
                                        }
                              #endif
                              }
                              
                              
                              
                              MainWindow::~MainWindow()
                              {
                                  qDebug()<<"distructor";
                                  delete ui;
                              }
                              
                              void MainWindow::update_data()
                              {
                                  try
                                  {
                                  bool flag_btm_skip = false;
                                          retry_count ++;
                                          if(flag_top_connect)
                                          {
                                              if(retry_count >= 2)
                                              {
                                                  try
                                                  {
                                                  if(File_Class::read_file(global::PATH_SID_TOP_TEXT))
                                                  {
                                                      if(File_Class::File_data != "")
                                                      {
                                                         global::Cam1_sid = File_Class::File_data.trimmed();
                                                          qDebug()<<"SID TOP"<<global::Cam1_sid;
                                                          global::Top_SID_Connect = true;
                              
                                                      }
                                                      else
                                                      {
                                                          global::Top_SID_Connect = false;
                                                      }
                                                  }
                                                  else
                                                  {
                                                      global::Top_SID_Connect = false;
                                                  }
                                                  }
                                                  catch(...)
                                                  {
                                                      global::Top_SID_Connect = false;
                                                  }
                              
                                                      if(global::Btm_SID_Connect == false)
                                                      {
                                                          bottom_process_start();
                                                          retry_count = 0;
                                                          flag_btm_skip = true;
                                                      }
                                                      else
                                                      {
                                                           update_timer->stop();
                                                      }
                              
                              
                              
                                              }
                                              else
                                              {
                                                  try
                                                  {
                                                  if(File_Class::read_file(global::PATH_SID_TOP_TEXT))
                                                  {
                                                      if(File_Class::File_data != "")
                                                      {
                                                          global::Cam1_sid = File_Class::File_data.trimmed();
                                                          qDebug()<<"SID TOP"<<global::Cam1_sid;
                                                          global::Top_SID_Connect = true;
                              
                                                      }
                                                      else
                                                      {
                                                          global::Top_SID_Connect = false;
                                                      }
                                                  }
                                                  else
                                                  {
                                                      global::Top_SID_Connect = false;
                                                  }
                                                  }
                                                  catch(...)
                                                  {
                                                      global::Top_SID_Connect = false;
                                                  }
                              
                                                  if(global::Top_SID_Connect == false)
                                                  {
                                                      QProcess process_1;
                                                      process_1.startDetached("/bin/sh", QStringList()<< global::PATH_GET_SID_TOP);
                                                      update_timer->start(15000);
                                                  }
                                                  else
                                                  {
                                                      if(global::Btm_SID_Connect == false)
                                                      {
                                                          bottom_process_start();
                                                          retry_count = 0;
                                                          flag_btm_skip = true;
                                                      }
                                                      else
                                                      {
                                                           update_timer->stop();
                                                      }
                                                  }
                                              }
                                          }
                                          else if(flag_btm_connect)
                                          {
                                              if(retry_count >= 2)
                                              {
                                                  try
                                                  {
                                                  if(File_Class::read_file(global::PATH_SID_BTM_TEXT))
                                                  {
                                                      if(File_Class::File_data != "")
                                                      {
                                                          global::Cam2_sid = File_Class::File_data.trimmed();
                                                          qDebug()<<"SID Btm"<<global::Cam2_sid;
                                                          global::Btm_SID_Connect = true;
                                                      }
                                                      else
                                                      {
                                                          global::Btm_SID_Connect = false;
                                                      }
                                                  }
                                                  else
                                                  {
                                                      global::Btm_SID_Connect = false;
                                                  }
                                                  }
                                                  catch(...)
                                                  {
                                                      global::Btm_SID_Connect = false;
                                                  }
                                              }
                                              else
                                              {
                                                  try
                                                  {
                                                  if(File_Class::read_file(global::PATH_SID_BTM_TEXT))
                                                  {
                                                      if(File_Class::File_data != "")
                                                      {
                                                          global::Cam2_sid = File_Class::File_data.trimmed();
                                                          qDebug()<<"SID Btm"<<global::Cam2_sid;
                                                          global::Btm_SID_Connect = true;
                              
                                                      }
                                                      else
                                                      {
                                                          global::Btm_SID_Connect = false;
                                                      }
                                                  }
                                                  else
                                                  {
                                                      global::Btm_SID_Connect = false;
                                                  }
                                                  }
                                                  catch(...)
                                                  {
                                                      global::Btm_SID_Connect = false;
                                                  }
                              
                                                  if(global::Btm_SID_Connect == false)
                                                  {
                                                      QProcess process_2;
                                                      process_2.startDetached("/bin/sh", QStringList()<< global::PATH_GET_SID_BTM);
                                                      update_timer->start(15000);
                                                  }
                              
                                              }
                                              if((retry_count >= 2)||(global::Btm_SID_Connect == true))
                                              {
                                                  update_timer->stop();
                                              }
                                          }
                                          QString str="";
                                          if(flag_TopCamEnable != 0)
                                          {
                                              if(global::Top_SID_Connect == true)
                                              {
                                                  str = "Top Camera Connected";
                                              }
                                              else
                                              {
                                                  if(retry_count >= 2)
                                                  {
                              
                                                     str = "Top Camera unable to connect";
                                                  }
                                                  else
                                                  {
                                                      str = "Top Camera Connecting";
                                                  }
                                              }
                                          }
                              
                                          if(flag_BtmCamEnable != 0)
                                          {
                                           if(flag_btm_connect && (flag_btm_skip == false))
                                           {
                                              if(global::Btm_SID_Connect == true)
                                              {
                                                  str += "     Bottom Camera Connected";
                                              }
                                              else
                                              {
                                                  if(retry_count == 2)
                                                  {
                                                      // update_timer->stop();
                                                      str += "     Bottom Camera unable to connect";
                                                  }
                                                  else
                                                  {
                                                      str += "     Bottom Camera Connecting";
                                                  }
                                              }
                                           }
                                          }
                                        //  str += "  "+QString::number(retry_count);
                                          ui->lbl_status->setText(str);
                                          if(retry_count >= 2)
                                          {
                                              retry_count = 0;
                                          }
                                          flag_btm_skip = false;
                              
                                     if((global::Top_SID_Connect == true)&&(global::Btm_SID_Connect == true))
                                     {
                                         ui->btn_login->setEnabled(true);
                                         ui->btn_login->setText("Login");
                                     }
                                  }
                                  catch(...)
                                  {
                              
                                  }
                              }
                              
                              void MainWindow::top_process_starrt()
                              {
                              
                              }
                              
                              void MainWindow::bottom_process_start()
                              {
                                  try
                                  {
                                  QProcess process;
                                  process.startDetached("/bin/sh", QStringList()<< global::PATH_GET_SID_BTM);
                                  check_count = 0;
                                  update_timer->start(5000);
                                  flag_top_connect = false;
                                  flag_btm_connect = true;
                                  }
                                  catch(...)
                                  {
                              
                                  }
                              }
                              
                              
                              
                              
                              
                              void MainWindow::on_btn_login_clicked()
                              {
                              
                                  DlgLogin = new dlg_login(this);
                                  DlgLogin->set_level("0",JobStatus);
                                  int dlg_int = DlgLogin->exec();
                                  delete DlgLogin;
                                  if(dlg_int == QDialog::Accepted)
                                  {
                              
                                          this->close();
                                          FrmRun = new frm_run;
                                          FrmRun->show();
                              
                                          //delete this;
                                         // this->close();
                              
                              
                                  }
                              
                              
                              
                              
                              
                              }
                              
                              void MainWindow::on_btn_Exit_clicked()
                              {
                                  this->close();
                              }
                              
                              void MainWindow::on_btnFactorySetting_clicked()
                              {
                                  try
                                  {
                              
                              
                                  DlgLogin = new dlg_login(this);
                                  DlgLogin->set_level("1",0);
                                  int dlg_int = DlgLogin->exec();
                                  if(dlg_int == QDialog::Accepted)
                                  {
                                      QString str_level = "";
                                       current_user = dlg_login::get_current_user();
                                      QSqlQuery QRY;
                                      QString Query="select level from USER_DETAILS  WHERE login_name = '"+current_user+"'";
                              
                              
                                      if(Mysql_class::query.exec(Query))
                                      {
                              
                                          while(Mysql_class::query.next())
                                          {
                                              str_level = Mysql_class::query.value(Mysql_class::query.record().indexOf("level")).toString();
                                          }
                                      }
                              
                                      if(str_level == "1")
                                      {
                              
                                          frm_factory_setting::set_admin_flag(true);
                                         // flag_admin = true;
                                      }
                                      else
                                      {
                                          frm_factory_setting::set_admin_flag(false);
                                         // flag_admin = false;
                                      }
                              
                                       this->close();
                                       FrmFactory = new frm_factory_setting;
                                       FrmFactory->show();
                                  }
                                  }
                                  catch(...)
                                  {
                              
                                  }
                              }
                              
                              void MainWindow::on_btn_Report_clicked()
                              {
                              
                                  DlgReport = new dlg_report(this);
                                  DlgReport->exec();
                              }
                              
                              void MainWindow::on_btn_shut_down_clicked()
                              {
                                  try
                                  {
                                  QProcess process_1;
                              
                                  process_1.startDetached("/bin/sh", QStringList()<< global::PATH_SHUTDOWN);
                                  }
                                  catch(...)
                                  {
                              
                                  }
                              }
                              
                              void MainWindow::on_btn_retry_connection_clicked()
                              {
                                  try
                                     {
                                     retry_count = 0;
                                     if((global::Top_SID_Connect == false )||(global::Btm_SID_Connect == false))
                                     {
                                     if(global::Top_SID_Connect == false)
                                     {
                                         QProcess process;
                                         process.startDetached("/bin/sh", QStringList()<< global::PATH_GET_SID_TOP);
                                         check_count = 0;
                                         retry_count = 0;
                                         update_timer->start(5000);
                                         flag_top_connect = true;
                                         flag_btm_connect = false;
                                         ui->lbl_status->setText(" Top Camera Connecting wait...");
                                     }
                                     else if(global::Btm_SID_Connect == false)
                                     {
                                        // on_btn_Cam2_clicked();
                                         bottom_process_start();
                                         ui->lbl_status->setText(" Bottom Camera Connecting wait...");
                                     }
                                 //    else
                                 //    {
                                 //        ui->lbl_status->setText("Top Camera Connected and Bottom Camera Connected");
                                 //    }
                                     }
                                     }
                                     catch(...)
                                     {
                              
                                     }
                              
                              }
                              
                              

                              The application froze without any input from the user (the system was performing normal tasks of getting images from the camera every 750ms and updating data from serial count).
                              We have also kept a Timer in the main thread which tells the worker thread to get an image.

                              1 Reply Last reply
                              0
                              • dheerendraD Offline
                                dheerendraD Offline
                                dheerendra
                                Qt Champions 2022
                                wrote on last edited by
                                #15

                                Why are doing the infinite while in threads. If you do this definitely, main thread or any other thread will be unresponsive.

                                Dheerendra
                                @Community Service
                                Certified Qt Specialist
                                http://www.pthinks.com

                                D 2 Replies Last reply
                                0
                                • dheerendraD dheerendra

                                  Why are doing the infinite while in threads. If you do this definitely, main thread or any other thread will be unresponsive.

                                  D Offline
                                  D Offline
                                  dev_512
                                  wrote on last edited by
                                  #16

                                  @dheerendra Yes we were doing that just to check if main thread hangs because of worker thread getting stuck. (we used to while thread to forcefully hang the worker thread). Did you find any problem in the main thread code?

                                  1 Reply Last reply
                                  0
                                  • dheerendraD dheerendra

                                    Why are doing the infinite while in threads. If you do this definitely, main thread or any other thread will be unresponsive.

                                    D Offline
                                    D Offline
                                    dev_512
                                    wrote on last edited by
                                    #17

                                    @dheerendra At this point, we are fairly certain that the problem is in the main thread code. I have uploaded the main thread code in the previous comment. Please suggest any necessary changes that could solve the issue. 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