Results 1 to 20 of 29

Thread: Console Application cannot stop properly a thread

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Dec 2014
    Posts
    7
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Console Application cannot stop properly a thread

    I confirm that it is well working on Linux (Ubuntu) using CTRL+C but ONLY while lunching it from a shell.
    Doing the same thing using the QtCreator debugger only throw an EXCEPTION and nothing happen except breaking on the a.exec() line. If we click on CONTINUE command of the debugger, the process simply continue without stopping... weird !

    For Windows : I'll try the other stuff I mentioned in the previous post and I will come back here for conclusion.

  2. #2
    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: Console Application cannot stop properly a thread

    Quote Originally Posted by erakis View Post
    I confirm that it is well working on Linux (Ubuntu) using CTRL+C but ONLY while lunching it from a shell.
    Doing the same thing using the QtCreator debugger only throw an EXCEPTION and nothing happen except breaking on the a.exec() line. If we click on CONTINUE command of the debugger, the process simply continue without stopping... weird!
    That is perfectly normal, the debugger is intercepting the signal. Run the application without a debugger and it will behave as expected.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Oct 2009
    Posts
    483
    Thanked 97 Times in 94 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Console Application cannot stop properly a thread

    This might be coming a bit late, but I can confirm that SetConsoleCtrlHandler() definitely is the way to go. I have used it several times. I once wrote an OS-independent abstraction of a "termination handler" that would emit a Qt signal when receiving a termination request from the OS. The implementation for Windows console applications used SetConsoleCtrlHandler() and the design was roughly along these lines (but with some hiding of the internal structures):
    Qt Code:
    1. class Handler : public QObject {
    2. Q_OBJECT
    3. signals:
    4. void terminated();
    5. public:
    6. void emitTerminated() {
    7. emit terminated();
    8. }
    9. };
    10.  
    11. QMutex mutex;
    12. Handler *handler = NULL;
    13.  
    14. BOOL WINAPI winHandler(DWORD /*dwCtrlType*/) {
    15. QMutexLocker lock(&mutex);
    16. if (handler == NULL)
    17. return FALSE;
    18. handler->emitTerminated();
    19. return TRUE;
    20. }
    21.  
    22. void registerHandler() {
    23. QMutexLocker lock(&mutex);
    24. assert(handler == NULL);
    25. handler = new Handler;
    26. SetConsoleCtrlHandler(winHandler, TRUE);
    27. }
    28.  
    29. void unregisterHandler() {
    30. QMutexLocker lock(&mutex);
    31. handler->deleteLater();
    32. handler = NULL;
    33. SetConsoleCtrlHandler(winHandler, FALSE);
    34. }
    To copy to clipboard, switch view to plain text mode 
    You can then connect to the Handler::terminated() signal to be notified of the termination request.

  4. #4
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Console Application cannot stop properly a thread

    Quote Originally Posted by yeye_olive View Post
    You can then connect to the Handler::terminated() signal to be notified of the termination request.
    The QMetaObject::invokeMethod() should work in this case as well, i.e. inside winHandler(), without the need for global variables

    Cheers,
    _

  5. #5
    Join Date
    Oct 2009
    Posts
    483
    Thanked 97 Times in 94 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Console Application cannot stop properly a thread

    Quote Originally Posted by anda_skoa View Post
    The QMetaObject::invokeMethod() should work in this case as well, i.e. inside winHandler(), without the need for global variables
    I do not understand what you mean. The first argument of the QMetaObject::invokeMethod() call would still need to be stored in a global variable. In any case, there is no absolute need for the Handler class; one may invoke a slot on QCoreApplication::instance(), etc. Emitting a signal and letting the user decide who to connect it to just makes the design more modular (although evertything should be encapsulated and hidden behind a nicer interface). Besides, the mutex and the check (handler == NULL) are needed in case the user unregisters the handler when winHandler is about to run.

  6. #6
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Console Application cannot stop properly a thread

    Quote Originally Posted by yeye_olive View Post
    The first argument of the QMetaObject::invokeMethod() call would still need to be stored in a global variable.
    Not in the case of quitting the application.

    Quote Originally Posted by yeye_olive View Post
    Besides, the mutex and the check (handler == NULL) are needed in case the user unregisters the handler when winHandler is about to run.
    The Qt::QueuedConnection takes care of the thread crossing by sending the method invocation request as an event to the receiver object's thread event loop.

    Cheers,
    _

  7. #7
    Join Date
    Oct 2009
    Posts
    483
    Thanked 97 Times in 94 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Console Application cannot stop properly a thread

    Quote Originally Posted by anda_skoa View Post
    Not in the case of quitting the application.
    OK. This design is a bit more general in that it lets the user decide what to do with the notification.
    Quote Originally Posted by anda_skoa View Post
    The Qt::QueuedConnection takes care of the thread crossing by sending the method invocation request as an event to the receiver object's thread event loop.
    Yes, that is why I chose to rely on Qt's thread safe signal emission. That is not why the mutex is needed. The mutex is here because the receiver object might not exist any more when winHandler runs. After unregistering the handler, I cannot tell when winHandler will definitely never be run any more. The problem would be the same with a call to QMetaObject::invokeMethod() for QCoreApplication::quit(). I would have no guarantee that winHandler would not be run after the QCoreApplication object was deallocated (which I suppose could happen if the OS queued two invocations of winHandler, then one was performed, then the application started to quit and winHandler ran again).

  8. #8
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Console Application cannot stop properly a thread

    Well, in the case of QCoreApplication::instance() it is valid pointer until the application has be destroyed.
    Which happens after the return of main().

    How likely is this winHandler being called after the program has stopped?

    Cheers,
    _

  9. #9
    Join Date
    Oct 2009
    Posts
    483
    Thanked 97 Times in 94 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Console Application cannot stop properly a thread

    Quote Originally Posted by anda_skoa View Post
    How likely is this winHandler being called after the program has stopped?
    Granted, it is highly unlikely that winHandler executes sometime between the point where the QCoreApplication instance starts being destroyed and the point the program terminates, but, as far as I can tell by reading Microsoft's documentation, nothing guarantees that it cannot happen. In fact, the documentation does not say anything about what happens after a handler has been unregistered.

    Better safe than sorry.

  10. #10
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Console Application cannot stop properly a thread

    Quote Originally Posted by yeye_olive View Post
    Granted, it is highly unlikely that winHandler executes sometime between the point where the QCoreApplication instance starts being destroyed and the point the program terminates, but, as far as I can tell by reading Microsoft's documentation, nothing guarantees that it cannot happen. In fact, the documentation does not say anything about what happens after a handler has been unregistered.

    Better safe than sorry.
    So what makes the instance of the mutex safer than the instance of the application?

    Cheers,
    _

  11. #11
    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: Console Application cannot stop properly a thread

    There is a simple workaround for this chicken and egg problem - remove the handler before the application object is destroyed.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  12. #12
    Join Date
    Oct 2009
    Posts
    483
    Thanked 97 Times in 94 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Console Application cannot stop properly a thread

    Quote Originally Posted by anda_skoa View Post
    So what makes the instance of the mutex safer than the instance of the application?
    Nothing, really. The mutex probably stays a little while longer since it is a global variable while the QCoreApplication is usually allocated on the stack in main(), but this does not eliminate the problem. I suppose there is no way around it, since there is no way to synchronize with the thread executing the handler, if any.
    Quote Originally Posted by wysota View Post
    There is a simple workaround for this chicken and egg problem - remove the handler before the application object is destroyed.
    How does it solve anything? Unfortunately, removing the handler does not guarantee that it will not be subsequently run, hence the need for a check in the handler.
    Last edited by yeye_olive; 23rd December 2014 at 19:57.

  13. #13
    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: Console Application cannot stop properly a thread

    I don't know about Windows but in Unix there is no magic extra thread executing the handler, you can even designate a particular thread of the application to be executing a particular handler. Therefore the execution is synchronous with the flow of the program for one of the application threads therefore if no threads apart the main one outlive the application object, removing the handler before the application is destroyed makes sure the handler will not be called at any later point in time (as in after the application object dies).
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


Similar Threads

  1. properly exiting console application.
    By pdallair in forum Newbie
    Replies: 5
    Last Post: 20th September 2013, 05:20
  2. Replies: 4
    Last Post: 24th September 2012, 07:28
  3. Replies: 0
    Last Post: 3rd May 2012, 22:38
  4. want to get thread to stop when application exits
    By dan146 in forum Qt Programming
    Replies: 6
    Last Post: 2nd May 2012, 23:07
  5. Replies: 2
    Last Post: 18th April 2011, 08:36

Tags for this Thread

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.