Results 1 to 10 of 10

Thread: Terminating QThread error

  1. #1
    Join Date
    Jul 2007
    Posts
    35
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Terminating QThread error

    i have a thread which does long operation. while its operates i want to terminate thread. The thread isn't in loop.
    I have tried QThread::terminate() and QThread::wait() methods. But sometimes my program is freezing at QThread::terminate() method.
    I have searhed the forum. There is another way for this is using flags but i can't interfere in loop of thread because i am calling another function from external lib.
    Is there any other way for terminating thread.
    Thanks in advance
    Ramazan

  2. #2
    Join Date
    Jan 2006
    Location
    Munich, Germany.
    Posts
    111
    Thanks
    29
    Thanked 3 Times in 2 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Windows

    Default Re: Terminating QThread error

    You can use terminate() but nobody recommends doing that.

    What you should do is intersperse a control variable throughout your job - and break your job into small parts.

    So, when you sub-class QThread you should make a private variable :
    bool keepRunning;
    and rewrite stop() to include keepRunning = false;
    then your run() looks like this...
    Qt Code:
    1. run()
    2. {
    3. keepRunning = true;
    4. //do some stuff
    5. if(!keepRunning) return;
    6. //do more stuff
    7. if(!keepRunning) return;
    8. //do even more stuff
    9. //etc
    10. }
    To copy to clipboard, switch view to plain text mode 

    here's my stop():
    Qt Code:
    1. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    2. /// wrapper for stopping the thread gracefully
    3. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    4. bool BaseDevice::stop (unsigned long time )
    5. {
    6. keepRunning = false;
    7.  
    8. QThread::quit();
    9. return QThread::wait(time);//returns false if timedout
    10. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by jpn; 29th July 2008 at 15:32. Reason: missing [code] tags

  3. #3
    Join Date
    Nov 2007
    Posts
    53
    Thanked 3 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Terminating QThread error

    Quote Originally Posted by TheKedge View Post
    You can use terminate() but nobody recommends doing that.

    What you should do is intersperse a control variable throughout your job - and break your job into small parts.
    I wake up this post as I have such a problem. I dealt with it on Windows by using an ugly construct with terminate() but on Linux / OS X, it makes a beautiful segmentation fault.

    As the original writer of this post said, this is not already possible to break a task in several parts, especially if you are using an external library.

    This is my case as I use gSOAP. My application is multi-windows relying on a static QModel shared between the windows. When the last windows is closed (the app is stil runing in the systray), the model is destroyed, so the thread owned by the QModel is destroyed as well.

    I've tried a clean code like in Qt samples with a wait() call.

    But, as I have simulated slow connections, wait() could freeze the application for 10 or 20 seconds before the thread is destroyed and the app won't react to sollicitations (new window opening when double-clicking on the systray nor contextual systray menu as well).

    So is there other solutions ?

    My idea is to use a timer or other thread that could be notified when a worker thread should be destroyed after it has finished his job. In this way, the timer or monitoring thread could asked periodically to the worker thread if it has finished running then be deleted when it is ok.

  4. #4
    Join Date
    Nov 2007
    Posts
    53
    Thanked 3 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Terminating QThread error

    Hmmm it seems my idea is hard to implement has it seems that Qt doesn't like to interact with a QMutex in a dynamically created thread, both statically and dynamically

  5. #5
    Join Date
    Nov 2007
    Posts
    53
    Thanked 3 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Terminating QThread error

    Nobody has a solution ?

    It is really important for the application not to crash and still reacting (so not waiting for the thread termination that depends on the gSOAP ending its HTTP call) when I close a windows.

    I can't use on the heap allocation for the threads because Qt doesn't really like that (I've got error messages related to QMutex).

    The problem is really with the terminate() call that works on Windows but leads to a segmentation fault on an UNIX system.

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

    Default Re: Terminating QThread error

    Using terminate() is Bad(TM) because you never know what is the current state of the thread when you try terminating it and the best that can happen is to get a segfault

    I don't know what you want to use mutexes for, but if it doesn't work then you must have done something wrong - QThread and QMutex work quite well with each other regardless of how the thread is created.

    Is your application a soap server or a soap client? Can't you check a stop variable in soap code and terminate the request when you see a raised flag?

  7. #7
    Join Date
    Nov 2007
    Posts
    53
    Thanked 3 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Terminating QThread error

    Yes, I know that it is bad and this is clearly told in the Qt documentation. But when you have no other choice...

    In any case, I've found the solution to avoid the crash on UNIX systems.

    But let's answer to your questions first.

    In fact, my thread use the same construct as the mandelbrot example for example so there is a QMutex protecting access to members variables in the same way.

    What I told in my previous posts is that I had tried to do stuffs like :

    MyThread *thread = new MyThread();

    In this way, I thought I could have started a timer in the QApplication class from the destructor of thread's parent but it doesn't work if you have mutexes in the thread.

    If you have an "on the stack" QMutex, Qt will complain about a pointer alignement problem. If you have an "on the heap" QMutex, you will have access violation.

    My application is a soap client but as it is multi-windows, I don't want an user with a slow connection closing a window then crashing the app or freezing the app until the result of the gSOAP call.

    But I have the solution, I've put this in the thread destructor :


    Qt Code:
    1. MyThread::~MyThread()
    2. {
    3. mutex.lock();
    4. quit = true;
    5. cond.wakeOne();
    6. mutex.unlock();
    7.  
    8. wait(100);
    9. if(isRunning())
    10. {
    11. terminate();
    12. wait(); // needed for UNIX systems
    13. }
    14.  
    15. delete service;
    16. }
    To copy to clipboard, switch view to plain text mode 

    From the mandelbrot sample, the difference is I put 100 ms for the wait so after 100 ms, if the thread is not terminated, the evil terminate() call is triggered.

    It was perfect on Windows, not on Linux / OS X. But by adding a second wait() as told in the Qt documentation :

    "Use QThread::wait() after terminate() for synchronous termination."

    it is now perfect.

    I don't have conflict with the state of my thread indeed because if this is a writing soap call, I forbid the window closing, I let the user doing it only if it is a read access so no problem.
    Last edited by jpn; 25th August 2008 at 07:16. Reason: missing [code] tags

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

    Default Re: Terminating QThread error

    Quote Originally Posted by nooky59 View Post
    In this way, I thought I could have started a timer in the QApplication class from the destructor of thread's parent but it doesn't work if you have mutexes in the thread.
    I don't really understand what you mean.

    If you have an "on the stack" QMutex, Qt will complain about a pointer alignement problem. If you have an "on the heap" QMutex, you will have access violation.
    What is the exact code you used?

    My application is a soap client but as it is multi-windows, I don't want an user with a slow connection closing a window then crashing the app or freezing the app until the result of the gSOAP call.
    Can't gSOAP make asynchronous calls? Anyway gSOAP call hangs on some system call like read and you can send a signal to cause it to return immediately with EINTR. Then you'll be able to shut down the thread.

    But I have the solution, I've put this in the thread destructor :
    Still, using terminate is dangerous. Of course if your application doesn't do anything serious, consequences will also be minimal.

  9. #9
    Join Date
    Nov 2007
    Posts
    53
    Thanked 3 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Terminating QThread error

    Quote Originally Posted by wysota View Post
    I don't really understand what you mean.


    What is the exact code you used?
    I tried to reproduce it on the mandelbrot sample and I had no problems. Then, I've thought immediately where I could have done a mistake previously (even if I didn't keep the tried code) !!!

    MyThread *thread = new MyThread();

    in the constructor of my class !!! I instanciate a local object to my constructor rather than using the member :

    thread = new MyThread();

    I was quite tired, sorry !

    Can't gSOAP make asynchronous calls? Anyway gSOAP call hangs on some system call like read and you can send a signal to cause it to return immediately with EINTR. Then you'll be able to shut down the thread.
    I haven't seen such a thing in the documentation. You can use asynchronous call only for one way messages so if you don't need an answer.

    You can only deal with time-out but this is not a solution I want for the reactivity of my app.

    Moreover, the documentation say :

    ---
    Caution: Many Linux versions do not support non-blocking connect(). Therefore, setting soap.connect_timeout for non-blocking soap_call_ns__method calls may not work under Linux.
    ---

    Still, using terminate is dangerous. Of course if your application doesn't do anything serious, consequences will also be minimal.
    I will listen to you even if it works now and if I think there could not conducts to problems (but the application does something serious because it deals with customers data).

    Now that I have found my mistake regarding on the heap QThread allocation, I could manage myself when the thread should be destroyed.

    So if the QThread's theorical parent (I won't give this to the QThread constructor to avoid cascading deletion process of Qt) is to be destroyed, I could now launch a monitoring code in the QApplication object, from the QThread's parent destructor that will destroyed the thread after it has properly terminate his job.

    Thanks for your answers and to tell me that it is still very bad to deal with evil ;o)
    Last edited by nooky59; 22nd August 2008 at 13:23.

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

    Default Re: Terminating QThread error

    Quote Originally Posted by nooky59 View Post
    (but the application does something serious because it deals with customers data).
    In that case I'd look for a safer solution.

    Thanks for your answers and to tell me that it is still very bad to deal with evil ;o)
    Mmm... easy the Dark Side seems to be... Once the path you enter, not able to withdraw you will be even if to senses quickly you come back, young padawan...

Similar Threads

  1. nmake error during .pro compiling
    By mattia in forum Installation and Deployment
    Replies: 5
    Last Post: 18th June 2008, 10:15
  2. Compile 4.4.0
    By LordQt in forum Installation and Deployment
    Replies: 18
    Last Post: 29th May 2008, 13:43
  3. QPSQL driver in windows
    By brevleq in forum Installation and Deployment
    Replies: 31
    Last Post: 14th December 2007, 12:57
  4. Error compiling psql plugin
    By vieraci in forum Installation and Deployment
    Replies: 4
    Last Post: 7th October 2007, 02:49
  5. qt 4.2.2 install on aix
    By try to remember in forum Installation and Deployment
    Replies: 2
    Last Post: 28th March 2007, 12:19

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.