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

Thread: Console Application cannot stop properly a thread

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

    Question Console Application cannot stop properly a thread

    Hi,

    I would like to create a thread that is polling a serial port continuously. The application will be a deamon or a service (according the platform). But for now I'm developing using a Console application on Windows because it is more easy to debug.

    The idea should be to create a thread and this thread will run forever or until the console application is closed. But just before the console closed itself it should wait until the thread finished. Thus, the console application should signal to the thread to stop. The main loop of the thread could poll a boolean or an event for that. This is what I call closing an application properly.

    Now, I read a lot of documentation of QT Reference, Google, etc... But I never get this working *properly*.

    Once I click on the X button of the console, or pressing key CTRL+C, the application close itself without having chance to signal to the thread to stop. How can I free resource used by the thread before it stop ? Worst, I'm asking to myself how the thread is stop ? Does it stop because it parent process has been killed ? If yes, this can lead to memory leak.

    Here is what I've done (test code, forget about scope, bad design please or deriving class from QThread):

    Qt Code:
    1. #include <QCoreApplication>
    2. #include <QThread>
    3. #include <QDebug>
    4. #include <csignal>
    5.  
    6. class WorkerThread : public QThread
    7. {
    8. public:
    9. explicit WorkerThread (QObject *parent = 0)
    10. :m_bStopThread(false) { }
    11.  
    12. private:
    13. void run()
    14. {
    15. // Thread run forever or until m_bStopThread = true
    16. while (!m_bStopThread)
    17. {
    18. qDebug() << "Worker thread operation... " << currentThreadId();
    19. QThread::msleep(1000);
    20. }
    21. return; // This breakpoint will never be triggered once the application is stop using X button of the windows or CTRL+C keyboard keys.
    22. }
    23. public :
    24. volatile bool m_bStopThread;
    25.  
    26. public Q_SLOTS:
    27.  
    28. void aboutToQuitApp()
    29. {
    30. m_bStopThread = true; // This breakpoint will never be triggered once the application is stop using X button of the windows or CTRL+C keyboard keys.
    31. }
    32. };
    33.  
    34. // This struct is a tips that I get from a forum that is supposed to catch the application closing. But it does not really work at all.
    35. struct CleanExit
    36. {
    37. static WorkerThread* pWorkerThread;
    38.  
    39. CleanExit(WorkerThread* _pWorkerThread)
    40. {
    41. CleanExit::pWorkerThread = _pWorkerThread;
    42.  
    43. signal(SIGINT, &CleanExit::exitQt);
    44. signal(SIGTERM, &CleanExit::exitQt);
    45. signal(SIGBREAK, &CleanExit::exitQt) ;
    46. }
    47.  
    48. static void exitQt(int sig)
    49. {
    50. // This breakpoint will be triggered only while using CTRL+C to close the application.
    51. // But the debugger loses his way as soon as I step further...
    52. // It is as if the application was already being closed and that I have no control on the
    53. // worker thread. The system has kill the thread because its parent process has been killed.
    54. pWorkerThread->m_bStopThread = true;
    55. pWorkerThread->wait();
    56.  
    57. QCoreApplication::exit(0);
    58. }
    59. };
    60. WorkerThread* CleanExit::pWorkerThread = NULL;
    61.  
    62. int main(int argc, char *argv[])
    63. {
    64. QCoreApplication a(argc, argv);
    65.  
    66. WorkerThread wk;
    67. CleanExit cleanExit(&wk);
    68.  
    69. QObject::connect(&wk, SIGNAL(finished()), &a, SLOT(quit()));
    70.  
    71. // The signal aboutToQuit [B]does not seem to work using Console Application[/B].
    72. QObject::connect(&a, SIGNAL(aboutToQuit()), &wk, SLOT(aboutToQuitApp()));
    73.  
    74. qDebug() <<"Starting worker thread ..." << QThread::currentThreadId();
    75. wk.start();
    76.  
    77. // Wait until the worker thread has finished his work !
    78. wk.wait();
    79.  
    80. // Close the console application
    81. return a.quit();
    82. }
    To copy to clipboard, switch view to plain text mode 

    Just read the comments, all my questions/problem are here.

    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

    Well, aside from the obvious question why you need a thread in the first place and the also unavoidable hint that you have a race condition:

    the operating system will free all memory allocated to you process and it will terminate the thread.
    It might not be able to do any specific cleanup though.

    Have you tried not installing your own signal handler but stopping the thread after QCoreApplication::exec() has returned?

    Cheers,
    _

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

    Default Re: Console Application cannot stop properly a thread

    First, thank for you quick anwser

    I am relatively novice with Qt and as I read on the QT Reference, the main loop (the code executed in the exec of the QCoreApplication) handle message pump. If I am not using any thread and I am doing a while (bStop) in the main, the QCoreApplication will never have the opportunity to handle any message ? Thus, how the closing event will be detected ? In addition, if (to handle event) I must called "ProcessEvent", this will slow down the operation of my serial port that are time crucial. Maybe you have a better solution ?

    What do you mean by "race condition" ? If the console application would received a "CLOSING" event, I could signal to my thread to :
    1. Stop
    2. Clean resources properly
    3. Call "join" on this thread from the main thread to wait until the thread is properly stopped
    4. Finally, letting the console application close


    I've done this a lot of time on Windows Win32/MFC and it is well working and I think it is the way to go for this kind of job. But now I have to use QT as this application will be deamon/service and could be use either on Windows or Linux.

    the operating system will free all memory allocated to you process and it will terminate the thread.
    Yes, I am aware of that but the OS will only MEMORY but it will not free other kind of resource/condition in consideration.

    Have you tried not installing your own signal handler but stopping the thread after QCoreApplication::exec() has returned?
    Could you help me with that ? Some example code would be appreciated please.

    Best regards,

  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
    I am relatively novice with Qt and as I read on the QT Reference, the main loop (the code executed in the exec of the QCoreApplication) handle message pump. If I am not using any thread and I am doing a while (bStop) in the main, the QCoreApplication will never have the opportunity to handle any message ?
    Yes

    Quote Originally Posted by erakis View Post
    Thus, how the closing event will be detected ? In addition, if (to handle event) I must called "ProcessEvent", this will slow down the operation of my serial port that are time crucial. Maybe you have a better solution ?
    I am mostly asking because I/O is Qt is usually done event driven, e.g. sockets, but also serial port.
    So I was wondering if you are sure you'll need a thread and all the things that come with multithreaded programming.

    Quote Originally Posted by erakis View Post
    What do you mean by "race condition" ?
    In multithread programming that refers to access to a shared resource, e.g. memory, by two threads without the necessary synchronization.
    Also called a data race.
    In your case one thread writing a variable and the other reading it.

    Quote Originally Posted by erakis View Post
    If the console application would received a "CLOSING" event
    This usually means that the Qt installed signal handler exits the main event loop.

    Have you tried with a simple program without any thread?
    Just a QCoreApplication that execs and print something after the exec call?

    Cheers,
    _

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

    Default Re: Console Application cannot stop properly a thread

    Hi,


    So I was wondering if you are sure you'll need a thread and all the things that come with multithreaded programming.
    We need a Thread because we have use the QSerialPort class using event driven but it is not as fast as sync way. And the way it is implemented (using event driven) causes us implementation issue for our custom protocol.

    In multithread programming that refers to access to a shared resource, e.g. memory...
    Yes I exactly know what is a "race condition" But I was asking WHY you said that ? The variable m_bStopThread is mark as VOLATILE to avoid cache reading. And don't forget that this example code was keep short to understand. In production I would use a mutext to protect those variables. Even if there was a race condition (in this context example), this would not prevent the closing detection mechanism of the application to stop the thread.

    Have you tried with a simple program without any thread
    Yes, with a single while (s_bStopThread) in the main and having the s_bStopThead be STATIC variable. Same probleme, no breakpoint hits, no printf in release mode. This do not work.

    What I've read on the subject is that SIGNAL handler are called from an external thread own by the OS. So when this thread is trying to change our local variable (s_bStopThread), this crash or do nothing as they are not hosted on the same process. As a workaround we could use a kind of process shared memory to signal to the main application to stop the thread before returning from the signal handler. Here is a link to a way to do that (LINUX only) : https://qt-project.org/doc/qt-4.7/unix-signals.html. I've run this example on Linux and when I'm using CTRL+C the program does NOTHING. Thus, What I conclude is that it does not work I've also implemented this example for Windows (using PIPE and UPD socket) but this is SIMPLY NOT WORKING too.

    Database server are often implemented as a service or daemon and are build using a a console application as we are trying to do now. Sure they use one or many thread internally. How they stop their thread properly while getting a SIGTERM ? If they do not do it and kill the application, say it the middle of creating a table... there would corrupt the database! I don't talk about getting the power off on the computer by pulling the cable but rather stopping the deamon or service using an interface or CTRL+C.

    Best regards,
    Last edited by erakis; 10th December 2014 at 15:45.

  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 erakis View Post
    We need a Thread because we have use the QSerialPort class using event driven but it is not as fast as sync way. And the way it is implemented (using event driven) causes us implementation issue for our custom protocol.
    Ah, I see.
    One thing you should still try is to use event driven QSerialPort but in its own thread.
    I.e. making sure the serial thread only has to process serial e

    Quote Originally Posted by erakis View Post
    Yes I exactly know what is a "race condition" But I was asking WHY you said that ? The variable m_bStopThread is mark as VOLATILE to avoid cache reading.
    Nope. That keyword prevents the compiler from optimzing access to the variable.

    The only way to achieve lock-free value exchange is to use atomics, e.g. QAtomicInt

    Quote Originally Posted by erakis View Post
    And don't forget that this example code was keep short to understand. In production I would use a mutext to protect those variables
    The problem seems to be synchronisation between two threads, so threading issues need to be taken into account.
    An example is only good when it is accurate.

    Quote Originally Posted by erakis View Post
    Even if there was a race condition (in this context example), this would not prevent the closing detection mechanism of the application to stop the thread.
    How so?
    If the value never reaches the second thread, how would it know to stop?

    Quote Originally Posted by erakis View Post
    What I've read on the subject is that SIGNAL handler are called from an external thread own by the OS. So when this thread is trying to change our local variable (s_bStopThread), this crash or do nothing as they are not hosted on the same process. As a workaround we could use a kind of process shared memory to signal to the main application to stop the thread before returning from the signal handler. Here is a link to a way to do that (LINUX only) : https://qt-project.org/doc/qt-4.7/unix-signals.html. I've run this example on Linux and when I'm using CTRL+C the program does NOTHING. Thus, What I conclude is that it does not work I've also implemented this example for Windows (using PIPE and UPD socket) but this is SIMPLY NOT WORKING too.
    I'll have to try that myself. Should have time for that tomorrow, hopefully.

    Cheers,
    _

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

    Default Re: Console Application cannot stop properly a thread

    Hi anda

    We are shot in time but we don't have any other solution so sure, give a try when you'll have free time It will be appreciated.

    If the value never reaches the second thread, how would it know to stop?
    I did tried using mutext, do you agree with me that the condition (variable) would be protected. The thread ONLY read the variable and do not change its value. The only thread changing the value of the variable is the external thread for the signal handler.

    By the way, "OPTIMIZING" accesss for volatile keyword was a better definition than mine, thanks. But the idea was to explain you that I care about the variable shared access between the threads. Only ONE writter single writter so even if we were using an ATOMIC way, mutex, or any other sync method, the example should work anyway in this case.

    Best regards,

  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

    This works for me (on Linux)
    Qt Code:
    1. #include <QtCore>
    2.  
    3. #include <signal.h>
    4.  
    5. class Thread : public QThread
    6. {
    7. public:
    8. explicit Thread(QSemaphore &s, int id, QObject *parent = 0)
    9. : QThread(parent)
    10. , m_semaphore(s)
    11. , m_id(id)
    12. , m_stop(false)
    13. {
    14. }
    15.  
    16. void stop()
    17. {
    18. QMutexLocker locker(&m_mutex);
    19. m_stop = true;
    20. }
    21.  
    22. void run()
    23. {
    24. qDebug() << "Starting secondardy thread" << m_id;
    25.  
    26. while(!shouldStop()) {
    27. msleep(10);
    28. }
    29.  
    30. qDebug() << "Secondary thread" << m_id << "exiting";
    31. m_semaphore.release();
    32. }
    33.  
    34. private:
    35. mutable QMutex m_mutex;
    36. QSemaphore &m_semaphore;
    37. int m_id;
    38. bool m_stop;
    39.  
    40. private:
    41. bool shouldStop() const
    42. {
    43. QMutexLocker locker(&m_mutex);
    44. return m_stop;
    45. }
    46. };
    47.  
    48. void signalHandler(int signalNumber)
    49. {
    50. qDebug() << Q_FUNC_INFO << signalNumber;
    51.  
    52. QMetaObject::invokeMethod(QCoreApplication::instance(), "quit", Qt::QueuedConnection);
    53. }
    54.  
    55. int main(int argc, char **argv)
    56. {
    57. QCoreApplication app(argc, argv);
    58.  
    59. signal(SIGINT, signalHandler);
    60. signal(SIGTERM, signalHandler);
    61.  
    62. QSemaphore semaphore(0);
    63.  
    64. QVector<Thread*> threads(10);
    65. for (int i = 0; i < threads.count(); ++i) {
    66. threads[i] = new Thread(semaphore, i);
    67. threads[i]->start();
    68. }
    69.  
    70. qDebug() << "Starting Main thread event loop";
    71. int ret = app.exec();
    72.  
    73. for (int i = 0; i < threads.count(); ++i) {
    74. threads[i]->stop();
    75. }
    76. semaphore.acquire(threads.count());
    77.  
    78. qDeleteAll(threads);
    79.  
    80. qDebug() << "Main thread exiting";
    81. return ret;
    82. }
    To copy to clipboard, switch view to plain text mode 

    Cheers,
    _

  9. #9
    Join Date
    Mar 2008
    Location
    Kraków, Poland
    Posts
    1,536
    Thanked 284 Times in 279 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Console Application cannot stop properly a thread

    Also works under Windows.

  10. #10
    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,

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

  12. #12
    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 18:31.

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

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

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


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

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

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

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

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

Similar Threads

  1. properly exiting console application.
    By pdallair in forum Newbie
    Replies: 5
    Last Post: 20th September 2013, 06:20
  2. Replies: 4
    Last Post: 24th September 2012, 08:28
  3. Replies: 0
    Last Post: 3rd May 2012, 23:38
  4. want to get thread to stop when application exits
    By dan146 in forum Qt Programming
    Replies: 6
    Last Post: 3rd May 2012, 00:07
  5. Replies: 2
    Last Post: 18th April 2011, 09: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.