QThread freezing the UI!
-
Confirming that the threads are different... Below a simple output.
Each thread prints its own address (converted to ulong) and where they are (Worker or Form)...Form - Thread: 9047552 Worker - Thread: 54738656 Worker - Thread: 54738656 Worker - Thread: 54738656 Form - Thread: 9047552 Worker - Thread: 54738656 Worker - Thread: 54738656 Worker - Thread: 54738656 Worker - Thread: 54738656 Form - Thread: 9047552 Form - Thread: 9047552
-
check out this fork smaple
-
@andsun said:
check out this fork smaple
There is no need to fork() if you use QThread.
@rkhaotix said:
Confirming that the threads are different... Below a simple output.
Each thread prints its own address (converted to ulong) and where they are (Worker or Form)...Did you print these values from inside
ExportWorker::exportBuffer()
?I've read somewhere that putting a thread to work with a loop can cause the mentioned behavior (CPU drain and UI freeze). But I need the export to work that way. Someone have any suggestion? A better approach?
I'm quite confusing and frustrated with all this and any help is welcome!You need to provide lots more information:
- Do you transfer any data between the 2 threads? If so, how?
- How is the buffer filled?
- Where does the exported data go?
- Which thread creates your QSqlDatabase object?
-
@andsun said:
check out this fork smaple
There is no need to fork() if you use QThread.
@rkhaotix said:
Confirming that the threads are different... Below a simple output.
Each thread prints its own address (converted to ulong) and where they are (Worker or Form)...Did you print these values from inside
ExportWorker::exportBuffer()
?I've read somewhere that putting a thread to work with a loop can cause the mentioned behavior (CPU drain and UI freeze). But I need the export to work that way. Someone have any suggestion? A better approach?
I'm quite confusing and frustrated with all this and any help is welcome!You need to provide lots more information:
- Do you transfer any data between the 2 threads? If so, how?
- How is the buffer filled?
- Where does the exported data go?
- Which thread creates your QSqlDatabase object?
@JKSH Thanks for you reply!
Answering your questions...
-
The only data I transfer between threads are messages and process progress through signals from Worker Thread to Form Thread (UI). Basically a QString and int instances.
-
The buffer is filled in the Worker side. It will call the method in database model instance that will produce a QString. After that I iterate line by line in that string using QTextStream.
-
The processed SQL for each object is then passed to a instance of a class called Connection (a libpq encapsulation made my me). I don't use the SQL/DB classes provided by Qt.
My project is open source but I won't post the code here due its size... If you have any interest here goes the links:
Form class: https://github.com/pgmodeler/pgmodeler/blob/develop/libpgmodeler_ui/src/modelexportform.cpp
Worker (or Helper) class: https://github.com/pgmodeler/pgmodeler/blob/develop/libpgmodeler_ui/src/modelexporthelper.cppSee methods ModelExportForm::exportModel() and ModelExportHelper::exportBufferToDBMS().
-
Hi @rkhaotix,
I had a quick look at your code. It's too big for me to go through properly, and I didn't spot anything obvious that maxes out your CPU.
However, I noticed a few things which might be related:
- Your ModelExportHelper constructor is run in the main thread, so it opens the DB connection in the main thread. Are you sure you can use that connection in the worker thread after this?
- In line 56 of modelexportform.cpp: the lambda runs in the signalling (GUI) thread, not the worker thread. Note that, while the QThread manages the worker thread, the QThread object itself lives in the GUI thread.
- Your ModelExportHelper uses some GUI-related classes: QGraphicsView, QPixmap. These classes must only be used in the GUI thread.
- Your ModelExportHelper includes "modelwidget.h". Why? Widgets must only be used in the GUI thread.