GUI freezes even with multithreading
-
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 no issues so far. Will update. Thank you.
-
@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.
-
Just see whether process is still running ? Just check it is a issue of memory ? Are there any memory leaks in your program ?
-
@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.
-
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 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. -
Why are doing the infinite while in threads. If you do this definitely, main thread or any other thread will be unresponsive.
-
@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?
-
@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.