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

    Hi all,

    Sanda, I've tried your sample code but there is something that I still not understand or maybe this solution still does not work

    On Windows I have added this small code part, just after releasing the semaphore :
    Qt Code:
    1. qDeleteAll(threads);
    2.  
    3. QFile file("C:\\qtThreadEnded.txt");
    4. file.open(QIODevice::WriteOnly | QIODevice::Text);
    5. QTextStream out(&file);
    6. out << "Application closing PROPERLY !!!\n";
    7. file.flush();
    8. file.close();
    To copy to clipboard, switch view to plain text mode 

    Simply to write a file when the application exit. Here is the way I've test :
    1. Task Manager [End Task]
      • I open the task manager, I click on the console process line and then I click on "End Task" menu. Usually the WM_CLOSE is send but as we are in a console application, no windows will handle this message ? But, is Windows smart enough to send a SIGTERM instead ? Anyway the application is closing and I can confirm you is that NO file has been written C:\\qtThreadEnded.txt.
    2. X button of console Window
      • I've read somewhere that End Task and clicking the X Button of the console Application do the same kind of kill on Windows. The application is closing but Still NO file has been written C:\\qtThreadEnded.txt.
    3. CTRL+C
      • The break point set in the signalHandler is hit, good news ! But application is not closing and still NO file has been written C:\\qtThreadEnded.txt.


    The fact that no file is written is indicating us that process is not exited as we WANT. The process is not waiting for thread to be stop, cleaning resource and stop process. Instead, the OS process closes abruptly the process.

    I have not tried on Linux, this is my next step.
    However, I want to thank you again for your help is much appreciated

    Best regards,

  2. #2
    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

    Since your target is a service, have you tried whatever shutdown method Windows uses for that?
    I.e. the equivalent to SIGTERM on Linux?

    As for the WM message, you could try with a native event filter in the application's event dispatcher and call quit() when this message arrives.

    As for the file: verify that you can actually write that file, e.g. write to it at the startup.

    I am afraid I don't know enough about process behavior on Windows, for all I know the things you are currently trying are equivalent to SIGKILL

    Cheers,
    _

  3. #3
    Join Date
    Dec 2014
    Posts
    7
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Console Application cannot stop properly a thread

    Before posting the preceding message I have already tried to write the file at the application startup and the file has been successfully written. So this is not the problem

    How can I intercept the message WM_CLOSE using event dispatcher ? Could you give me information ?

    I think Windows is using another mechanism for controller services.
    Ref : http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx
    But after reading on that, it seams to be very similar to POSIX signal.

    Also, I'm asking to myself on Windows if using "signal" function is not the right way ? Here is another information about signal handling on windows. Maybe using the "SetConsoleCtrlHandler" function will produce the same problem but I will give a try.
    Ref : http://msdn.microsoft.com/en-us/libr...8VS.85%29.aspx
    Ref : http://stackoverflow.com/questions/7...fferent-thread
    Ref : http://stackoverflow.com/questions/8...nup-operations

    I have not time yet to test on Linux but if you press CTRL+C, you confirmed that application is PROPERLY shutdown ?
    Last edited by erakis; 18th December 2014 at 17:31.

  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 erakis View Post
    How can I intercept the message WM_CLOSE using event dispatcher ? Could you give me information ?
    Each Qt event loop, e.g. the one of running QCoreApplication::exec(), is based on an implementation of QAbstractEventDispatcher.
    It passes all events it gets from whatever native event system it is based on to a chain of event filters.

    An application can install its own native event filter, see https://qt-project.org/doc/qt-5-snap...iveEventFilter

    Assuming this WM_CLOSE you mentioned earlier is some form of Windows native event, it should be detectable by your filter.

    Quote Originally Posted by erakis View Post
    I have not time yet to test on Linux but if you press CTRL+C, you confirmed that application is PROPERLY shutdown ?
    Yes. Also worked with kill -INT and kill -TERM

    For example with CTRL+C it looks like this
    Qt Code:
    1. ./threadexittest
    2. Starting Main thread event loop
    3. Starting secondardy thread 7
    4. Starting secondardy thread 3
    5. Starting secondardy thread 0
    6. Starting secondardy thread 1
    7. Starting secondardy thread 2
    8. Starting secondardy thread 8
    9. Starting secondardy thread 5
    10. Starting secondardy thread 9
    11. Starting secondardy thread 6
    12. Starting secondardy thread 4
    13. ^Cvoid signalHandler(int) 2
    14. Secondary thread 1 exiting
    15. Secondary thread 5 exiting
    16. Secondary thread 9 exiting
    17. Secondary thread 7 exiting
    18. Secondary thread 6 exiting
    19. Secondary thread 3 exiting
    20. Secondary thread 4 exiting
    21. Secondary thread 8 exiting
    22. Secondary thread 0 exiting
    23. Secondary thread 2 exiting
    24. Main thread exiting
    To copy to clipboard, switch view to plain text mode 

    Cheers,
    _

  5. #5
    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.

  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: 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.


  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

    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.

  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

    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,
    _

  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
    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.

  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
    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,
    _

  11. #11
    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).

  12. #12
    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,
    _

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.