Exiting Qt application does not kill spawned threads - c++

I have a Qt program that is using the QtConcurrent API to spawn worker threads. The problem I am having is that the worker threads keep going even if I exit the Qt application.
I have an actionExit in my menu, which is what i am using to close the app, or the "X" in the window corner. Is there any way to make these kill off all threads related to this app?
Thanks

Are you sure that the UI application really closes? You might be missing:
qApp->setQuitOnLastWindowClosed(true);
Otherwise QT only hides your window. To debug put a breakpoint behind your
mainWindow->exec(); and see whether it is really reached.
If you confirm that exec() returns and QTConcurrent really hangs (it might be possible: http://lists.trolltech.com/qt-interest/2008-06/thread00414-0.html), then do:
exit(0);

Related

when closing the qt application, want to kill qprocess

in my mainwindow.cpp, inside the constructor, I started a qprocess so the process(.exe) runs when I open the qt application.
Now I want to kill/close the qprocess when I close the qt application. How can I do it?
See the documentation for QProcess::terminate and QProcess::kill. They each have slightly different behavior. Use terminate to give the process a chance to shut down gracefully. Use kill to kill it more forcefully. In the case of terminate, you probably want to wait until the child process has finished (e.g. QProcess::waitForFinished) before exiting the parent process.

How to Run an event while another event is running in wxWidgets GUI?

I created one GUI having two buttons. one is start button and the other is stop button. when start is pressed the program will execute in the background and the gui will freeze. I couldn't control the window anymore. even a mouse click is not responding. the stop button is for stopping the program. since the window is not responding as it is running the program i cant press stop. what is the possible solution? .please help
A thread is sort of a subprogram inside your program. When the application starts it runs in the main thread. You can create many other threads; all of them (the main one included) share the application memory space (for example, same global vars in scope).
There are two kind of threads: "detached" and "joinable". detached threads delete themselves when they finish, think of them as "fire and forget". Conversely, joinable threads are deleted by yourself, only after they have completed their job.
In wxWidgets all GUI is executed in the main thread. Calling a GUI function from another thread is a nightmare, don't do it.
Your case is a typical situation. The "start" button launches a thread to do some job. If you want to cancel this job you push the "stop" button.
How to instruct the thread to cancel its job?
While you can use wxCondition, you can also set a flag on your own. The working thread reads at some moment this flag (it's not automagic, you must code it) and stops or continue depending on its value. Don't forget to use a wxMutex before accesing the flag to protect it from another thread changing it at the same time.
Also, threads can post messages to the main thread event-loop. This way you can tell the main thread that your worker thread has finished its job.
Threads require more attention when you're coding them. You must avoid some situations such as:
"dead lock": two threads wait one for each other, none finishes.
"race condition": several threads try to change a shared value at the same
time.
More on wxWidgets docs and thread sample.
Finally, C++11 has std::thread and other related friends (mutexes, semaphores, etc). It's your choice to use it instead of wxWidgets classes.

Disabling control variable while worker thread is finishing MFC

I am working on a dialog-based MFC Application using Visual Studio 2015. Basically my problem is that I have a button that will start a worker thread after the user has chosen the necessary inputs (.csv files that will be parsed and put into different vectors). To avoid complications, I decided that the user will not be able to press this button or the input buttons until after the calculation done by the worker thread has finished. I tried the WaitforSingleObject options but defeats the purpose of keeping the main thread or the MFC Application running while waiting for the worker thread to finish. Is there any other workaround around this problem? I appreciate any help.
Your worker thread could post a completion message back to your UI thread. Your UI thread wouldn't need a special message loop in that case, instead your window procedure would then reenable the buttons when it receives that message.
You could use the MsgWaitForMultipleObjects function:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms684242(v=vs.85).aspx
ATL uses it in AtlWaitWithMessageLoop(https://msdn.microsoft.com/en-us/library/26hwk2bx.aspx).

Making a music player in C++/GTK

I would like to create a music player, but I'm working with robots.
My robot should play a series of action (speech, move, etc) and I need to be able to stop it at anytime (for security).
I'm working with C++ and GTK.
I have a PLAY button linked to the function play_playlist:
void play_playlist ()
{
std::deque<history_record>::iterator it = list_to_play_.begin();
while (!g_stop_ && it != list_to_play_.end())
{
play_action(it); // take time to execute (simulate using sleep 3sec)
it++;
}
}
And a STOP button linked to the function set_stop_to_false:
void set_stop_to_true()
{
g_stop_ = true;
}
When I click PLAY the GUI freezes and I'm not able to click on STOP.
How can I have my playlist running and be able to click on the GUI? (i.e. GUI should be responsive)
My best hope is a thread, but I'm not sure how to use it appropriately.
When I click PLAY the GUI freezes and I'm not able to click on STOP.
You need to build a multi-threaded application. Your interface freezes because your application is busy doing something else, so not only that events raised from GUI are not being processed but they are not even raised.
Your application should start a worker thread that will do its job in the background, the main thread can then communicate with this worker thread for example via shared memory.
Once you enter a callback like play_playlist, the GTK main loop can't process events until you exit that function, which freezes the user interface. As play_action takes seconds to run, you only have 2 choices:
split play_playlist execution in several smaller steps, and use a
state machine to execute each step one after the other using a
callback triggered by g_idle_add. Here's an example of this
technique for lazy loading.
the other solution is to run your blocking play_action in a thread. Give a look at GThread. You start your thread when you press PLAY and stop it when you press STOP. However, you can't manipulate the user interface from a thread, GTK is not thread safe. Every GTK action should be processed from the main thread.

How do I create Modal dialog in worker thread(Non-UI thread)?

I have written a sample MFC application in which there are two threads:
-Main thread ( UI thread)
-Worker thread ( non-UI thread)
I have a specific requirement to create a Modal dialog in Non-UI ( worker thread).
When I create the CDialog object and call DoModal on the same, it works. The dialog gets created and acts as Modal to the application. ( Win XP SP2 machine) But this does not work in Windows 2003 server machine.
The behavior in 2003 server is that, the Modal Dialog goes behind the application main Window and dialog will be brought to front only when I click on Main Window. It is not acting as Modal dialog to my application.
What could be the problem -- any ideas?
If creating UI controls in non-UI thread is the issue then is there any Win32 API which will allow me to link my worker thread to Main UI thread such that DoModal happens in Main thread. I tried AttachThreadInput but it is not working.
There is no reliable way to spread GUI modality across multiple threads. Every window is represented by an object referenced through a HWND which in turn has thread affinity. This is a left-over from the 16-bit days of Windows, where there was no multi threading. Consequently the HWNDs are not protected against concurrent access. The Old New Thing has an excellent series on "Thread affinity of user interface objects" (Part 1 2 3 Addendum).
Modality is implemented by first enabling the dialog window and then disabling its parent. The first step is safe while the second attempts to disable a window from a thread which is not the window's owning thread. Since en-/disabling windows modifies the object referenced through the HWND it represents a race condition.
The suggested solution is to confine your GUI to a single thread and communicate from your worker thread to the GUI thread to have it perform user interaction on the worker thread's behalf. The easiest way to accomplish this is to call SendMessage from the worker thread to block until the GUI thread's message handler returns. If the worker thread should continue to run while the dialog is displayed you could use PostMessage instead and communicate back to the worker thread using PostThreadMessage or signaling a synchronization object like an Event Object.
First of all, I'd like to agree with other posters that it's probably better to show the dialog on the main UI thread.
However, if you must, you can make a dialog on another thread modal with the following steps:
Pass your active window as an owner when creating the dialog.
When dialog is showing, iterate over your other windows and do them EnableWindow(FALSE). When the dialog is hiding, do the reverse. You will probably have to remember windows' enabled state and restore the original state, not just EnableWindow(TRUE).
Ensure that accelerators and other global commands will be ignored while the dialog is shown.
Note that (2) shouldn't be necessary provided that you do (1), but you've mentioned MFC, and I don't remember exactly how it behaves. It has it's own modal dialog implementation which may not exactly match Win32. If you're lucky, (1) and (3) will be enough.
While i don't know about the specifics of dialog handling on Server 2003, the simplest workaround to get on the main thread would be to use a custom window message, do ::SendMessage() and display the dialog in the message handler.
I recommend you not to do what the question subject suggests, and confine all UI to one thread. If you need the other thread to communicate with the user, create some messaging mechanism that will ask the UI thread to do it, and transport the results back.