Page 1 of 2 12 LastLast
Results 1 to 20 of 27

Thread: Thread freezing GUI

  1. #1
    Join Date
    May 2007
    Posts
    90
    Thanks
    40
    Qt products
    Qt4
    Platforms
    Windows

    Question Thread freezing GUI

    I have a program that creates a variable number of threads to do work in the following way:

    Main GUI
    sub GUIs
    Thread for each sub GUI
    Thread that performs many io reads

    This is simplified, but this is the basic structure.

    My problem is this: the bottom thread freezes the top GUI.

    I can't show any code (belongs to my company not me).

    All of my objects are created in the run methods as they should be.

    Other windows in other applications don't show any signs of slowdown so it is not the cpu.

    Any Ideas?

    Thank You

  2. #2
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Thread freezing GUI

    Do you modify/create any widgets in any of the worker threads?
    How do the worker threads communicate with the corresponding GUI components?
    Do you use signals/slots for this or events or you call functions across threads directly?

    I'm asking because I can name a few reasons for your problem.

    Regards

  3. The following user says thank you to marcel for this useful post:

    TheGrimace (31st May 2007)

  4. #3
    Join Date
    May 2007
    Posts
    90
    Thanks
    40
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Thread freezing GUI

    The worker threads communicate via signals connected using the default connection type. (AutoConnect I believe).

    The only functions I call directly in the threads are the start methods.

    There is, however, another Widget-based plugin that I connect to sub threads whenever I create them.

    Do I need to explicitly make these Queue connections?

  5. #4
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Thread freezing GUI

    There is, however, another Widget-based plugin that I connect to sub threads whenever I create them.
    By connect do you mean at connecting them to the started() signal of a thread, I assume.

    The bottom line is that no widgets must live in other thread than the GUI thread.
    Qt::AutoConnection means Qt::QueuedConnection if receiving object does not live in the emitting thread, and Qt:irectConnection otherwise.

    You said that the threads are performing IO operations.
    I assume that they will read something from some device and update the GUI accordingly.
    A problem could be the rate at which you're updating the GUI.
    Sending a lot ( and I mean a lot ) of signals from the worker threads to the GUI could put some heavy load on the GUI's event handler.

    Regards
    Last edited by marcel; 30th May 2007 at 21:23.

  6. #5
    Join Date
    May 2007
    Posts
    90
    Thanks
    40
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Thread freezing GUI

    Not Really.

    I haven't explained it well.

    I create a Main GUI and a single DoThis Widget initially. The Main GUI then creates child widgets (tabs) based on user input. Each time a tab is created, the DoThis widget is connected to the sub threads signals. These signals are usually to tell the DoThis widget to do something.

    The place where the GUI hangs is during the io reads at the most sub thread. At that point the DoThis widget has yet to be called and everything is contained within the sub threads run method.

  7. #6
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Thread freezing GUI

    Well, some code would have been useful.
    But anyway, it depends on what DoThis actually does.
    If it has a slot ( or more ) connected to multiple threads, then several threads might ask it to do something, all at the same time.
    Sure, the signals from the threads, translated to events, will be handled sequentially by the GUI's event handler, but as I said, it depends on what DoThis has to do when it receives a signal.

    Someone posted about a similar problem some time ago, but he had a a lot of widgets in the tab widget. The problem came from the huge time needed to update the widgets contents and as well from repainting the widgets.

    So, if you can provide more details, then do it.

    BTW, the post is this: http://www.qtcentre.org/forum/f-qt-d...tabs-6902.html

    Regards

  8. #7
    Join Date
    May 2007
    Posts
    90
    Thanks
    40
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Thread freezing GUI

    Basically the program works like this:

    Main GUI just asks how many instances.

    Each sub widget has controls to find network information.

    The sub-widget creates a worker thread.

    This thred creates 2 sub threads, sub thread 2 is connected (in the run method) to the DoThis widget and sub thread 1 is connected to sub thread 2

    Sub Thread 1. Looks at the network and handles transmissions (parsing)and funnels commands to thread 2

    Sub Thread 2. When commands are received it looks at the hard drive and finds the appropriate file. When found it emits a signal grabbed by the DoThis Widget.

    The DoThis widget then creates its own thread and transmits the data.

    The only time that the GUI hangs is when thread 2 is looking at the hard drive.

    At no other point does the GUI hang (not even during network traffic or the DoThis widgets transmission)

    Thank you for the help, sorry I can't show code.
    Last edited by TheGrimace; 30th May 2007 at 21:57. Reason: reformatted to look better

  9. #8
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Thread freezing GUI

    Sub Thread 2. When commands are received it looks at the hard drive and finds the appropriate file. When found it emits a signal grabbed by the DoThis Widget.

    The DoThis widget then creates its own thread and transmits the data.

    The only time that the GUI hangs is when thread 2 is looking at the hard drive.
    But then it makes no sense, especially if you don't communicate with other threads when you're searching for that file.
    I really can't see the problem there, although it's obvious there is one.
    Sorry

  10. #9
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,363
    Thanks
    3
    Thanked 5,012 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Thread freezing GUI

    Quote Originally Posted by TheGrimace View Post
    Thank you for the help, sorry I can't show code.
    Could you provide a simple code example that works in a similar way to the copyrighted code? I mean something that creates threads and shows their relation and what they are doing. Especially the part related to "sub-GUIs" (and please explain what you mean by that term).

  11. #10
    Join Date
    May 2007
    Posts
    90
    Thanks
    40
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Thread freezing GUI

    In the Main GUI, I create an instance of DoThis GUI and pass a pointer to each tab that is created.

    Each tab then passes that pointer to its QThread
    Qt Code:
    1. PSUEDOCODE:
    2.  
    3.  
    4. Each Tab's QThread Run Method:
    5. run{
    6. // create new objects
    7. object_1 = new object1;
    8. object_2 = new object2;
    9. //each of these signals is called once per request
    10. connect(object2,signal,object1,slot)
    11. connect(object1,signal,object2,slot)
    12. connect(DoThis,signal,object1,slot)
    13. connect(object1,signal,DoThis,slot)
    14. object2->startTCPListener();
    15. object2->startUDPListener();
    16. exec();
    17. //disconnect and delete everything
    18. }
    To copy to clipboard, switch view to plain text mode 
    Object1 then has a slot like the following:

    Qt Code:
    1. readwriteLocker.lockforWrite();
    2.  
    3. listofObjects->add(new File_Thread);
    4. uniqueID = // a new unique ID
    5. listofObjects->at(listofObjects->count()-1)->setUniqueID(uniqueID);
    6.  
    7. readwriteLocker.unlock()
    8. readwriteLocker.lockforRead()
    9.  
    10. for(int i=0; listofObjects->count()>i ; i++)
    11. {
    12. if(listofObjects->at(i)->uniqueID == uniqueID)
    13. {
    14. listofObjects->at(i)->start();
    15. }
    16. }
    17. readwriteLocker.unlock()
    To copy to clipboard, switch view to plain text mode 
    The File_Thread finished signal is connected to a similar function that deletes the object.

    Here is what the File_Thread run method looks like:
    Qt Code:
    1. run{
    2. booleanRunning = true;
    3. find_File(); //This is where everything is done, emits, io accesses, everything
    4. //This is also where the gui slows down and becomes unresponsive
    5. booleanRunning = false;
    6. }
    To copy to clipboard, switch view to plain text mode 

    Thank You all for your interest and help.

    I hope this makes the problem more clear.
    Last edited by TheGrimace; 31st May 2007 at 16:56. Reason: reformatted to look better

  12. #11
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,363
    Thanks
    3
    Thanked 5,012 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Thread freezing GUI

    I meant something compilable...

  13. #12
    Join Date
    May 2007
    Posts
    90
    Thanks
    40
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Thread freezing GUI

    oh... sorry about that.

    I probably won't have time to make that.

  14. #13
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Thread freezing GUI

    About that thread that is searching the hard drive(s).
    You said that the GUI is freezing during that operation.
    But have you noticed any other application exhibiting weird GUI interactivity while yours freezes?

    Could you say at least what API are you using for searching the drive? And maybe describe a little the process?

    Regards

  15. The following user says thank you to marcel for this useful post:

    TheGrimace (1st June 2007)

  16. #14
    Join Date
    May 2007
    Posts
    90
    Thanks
    40
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Thread freezing GUI

    No. In fact all other GUIs have excellent response time during that period. I have checked the CPU usage, and it never gets above 10%

  17. #15
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Thread freezing GUI

    Qt Code:
    1. readwriteLocker.lockforWrite();
    2. listofObjects->add(new File_Thread);
    3. uniqueID = // a new unique ID
    4. listofObjects->at(listofObjects->count()-1)->setUniqueID(uniqueID);
    5. readwriteLocker.unlock()
    6. readwriteLocker.lockforRead()
    7. for(int i=0; listofObjects->count()>i ; i++)
    8. {
    9. if(listofObjects->at(i)->uniqueID == uniqueID)
    10. {
    11. listofObjects->at(i)->start();
    12. }
    13. }
    14. readwriteLocker.unlock()
    To copy to clipboard, switch view to plain text mode 
    I might have noticed something in that code.
    You create the File_Thread in some thread ( other than the GUI thread ) - thread X.
    Also you create thread X in some other thread - thread Y.
    Correct me if I'm wrong, but I think this is the general workflow of your app.

    The problem is that the slots for a thread will be executed in the context of the thread that created it.
    So, the slots of X are executed in the context of Y, the slots of Y in the context of the parent thread and so on.

    The solution is to change the affinity of the threads after they are started( you are provided with the started signal ). Changing affinity for an object means that you move the event processing for that object from the current thread to a target thread.

    So, for all your threads that have slots you must do the following after the thread starts:
    Qt Code:
    1. thread->moveToThread(thread);
    To copy to clipboard, switch view to plain text mode 
    I am not sure, but I think this might be the problem. Or at least one of the problems.

    EDIT: wherever you see slots please read events & slots!

    Regards

  18. The following user says thank you to marcel for this useful post:

    TheGrimace (1st June 2007)

  19. #16
    Join Date
    May 2007
    Posts
    90
    Thanks
    40
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Thread freezing GUI

    So I need to move the QThread object to its own run method?

  20. #17
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Thread freezing GUI

    No, you must call moveToThread for a thread, in it's parent thread after the subject thread starts( you will be notified by the started signal, which you must connect to slot in the parent thread ).

    You always start from the GUI thread so you're guaranteed that the parent thread's ( initially GUI thread ) event processing is done it it's context( the slot connected to the child thread's started signal is executed in the parent thread's context - which is GOOD ).

    By calling moveToThread you're making sure that any event( and signal ) the thread receives will be processed in the thread's context. For signals this means that the slot is executed in it's context.

    Right now the child threads may block their parent thread whenever they execute a slot or they process an event, because that will be done in the parent thread. So each child thread is eligible of blocking it's parent.

    I hope I made it clear.

    Also, apart from this, after you create the File_Thread, you assign it with a unique ID, but then you iterate through all the threads, stating the one with that ID.
    Why don't you just start the thread that you have just appended, because you know that is the new one? ( but this isn't really a problem, I was just curious why you went on the bumpier road ).

    Regards

  21. The following user says thank you to marcel for this useful post:

    TheGrimace (1st June 2007)

  22. #18
    Join Date
    May 2007
    Posts
    90
    Thanks
    40
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Thread freezing GUI

    For the starting issue, it was originally the way that you are saying, (and is that way again) I have just been trying everything I can think of to get the GUI (and a few dozen other issues) fixed.

    I am sorry to keep bugging you, but I am still a little confused.

    The structure exists like this:

    GUI Thread
    |
    Control Thread
    |
    Tons of objects
    |
    File_Thread


    That once Control Thread is started I move it to itself like:

    run{
    this->moveToThread(this);
    }

    or something else entirely?

    I am sorry i am just not getting it.

    Thank You for all of your help

  23. #19
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Thread freezing GUI

    OK.
    Maybe this helps you a bit:
    void QObject::moveToThread ( QThread * targetThread ) Changes the thread affinity for this object and its children. The object cannot be moved if it has a parent. Event processing will continue in the targetThread.
    To move an object to the main thread, use QApplication::instance() to retrieve a pointer to the current application, and then use QApplication::thread() to retrieve the thread in which the application lives. For example:
    myObject->moveToThread(QApplication::instance()->thread()); If targetThread is zero, all event processing for this object and its children stops.
    Note that all active timers for the object will be reset. The timers are first stopped in the current thread and restarted (with the same interval) in the targetThread. As a result, constantly moving an object between threads can postpone timer events indefinitely.
    Warning: This function is not thread-safe; the current thread must be same as the current thread affinity. In other words, this function can only "push" an object from the current thread to another thread, it cannot "pull" an object from any arbitrary thread to the current thread.
    Anyway, you should do something like this:
    Qt Code:
    1. void ParentThread::some_method()
    2. {
    3. childThread = new Thread();
    4. connect( childThread, SIGNAL( started() ), this, SLOT( childStarted() ) );
    5. childThread->start();
    6. }
    7.  
    8. void ParentThread::childStarted()
    9. {
    10. childThread->moveToThread( childThread() );
    11. }
    To copy to clipboard, switch view to plain text mode 
    I assume you can find a way to identify the last started child thread, so you can use it in childStarted().

    Regards

  24. The following user says thank you to marcel for this useful post:

    TheGrimace (1st June 2007)

  25. #20
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Thread freezing GUI

    Well, did it work?
    It often helps to reply and let us know if it really worked.

  26. The following user says thank you to marcel for this useful post:

    TheGrimace (4th June 2007)

Similar Threads

  1. KDE/QWT doubt on debian sarge
    By hildebrand in forum KDE Forum
    Replies: 13
    Last Post: 25th April 2007, 06:13
  2. Problem closing a QMainWindow in Qt4.2
    By ian in forum Qt Programming
    Replies: 11
    Last Post: 17th October 2006, 00:49
  3. simple thread layout question
    By mhoover in forum Qt Programming
    Replies: 1
    Last Post: 12th August 2006, 11:02
  4. [QT4] QThread and printing a QList<QPixmap>
    By KShots in forum Qt Programming
    Replies: 3
    Last Post: 24th April 2006, 21:44
  5. Replies: 2
    Last Post: 6th January 2006, 21:15

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.