In my application I have a modal dialog which contains about 20 different combo boxes which are bind to certain fields in the databases. The database is huge and on the loading of dialog I have to load all the combo boxes from the databases. So I setup 20 threads (1 each for every combo box).
Everything works fine, but the problem only occurs when the user closes the dialog with close or cancel button or OK button while the threads are running; in that case the application crashes.
I have tried to terminate the threads prematurely as well but that does not help. Here is the thread termination code
if(m_iNoOfThreadsCompleted != m_iTotalThreads)
{
for(int i = 0; i < m_iTotalThreads - 1; i++)
{
if (m_threads[i] != NULL)
{
GetExitCodeThread(m_threads[i]->m_hThread, &exit_code);
if(exit_code == STILL_ACTIVE)
CloseHandle(m_threads[i]->m_hThread);
}
if(m_iNoOfThreadsCompleted == m_iTotalThreads)
break;
}
}
What is the issue? Or do I need to use a better approach?
Synchronizing threads is generally done using events.
// Before Creating threads
HANDLE hEndEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
// Pass handle to threads
Then on termination
SetEvent(hEndEvent);
WaitForMultipleObjects(m_iTotalThreads,m_threads,TRUE,INFINITE); // Wait for all threads to end
// Loop through and close all the thread handles
Note that you need to be occasionally looking for the end event to be set otherwise your threads won't end.
// In Thread
if (WaitForSingleObject(hEndEvent,0)==WAIT_OBJECT_0) {
// Clean up
return 0;
}
CloseHandle does not terminate the thread. You can call TerminateThread but it's not the nicest thing to do...
What is normal is to provide your threads with a manual-reset event object that signals a shutdown is taking place. Sometimes it's also good to have a flag so that threads can abort lenghty operations. The threads carry on their work as usual, and whenever they have to wait on some object, you include the shutdown event object in that wait.
So the procedure on exit is normally to do this:
Set the shutdown flag
Signal the shutdown event
Resume all threads (in case any are suspended)
WaitForMultipleObjects on all thread handles, with an appropriate timeout
Call TerminateThread on any threads that did not exit within the timeout
Close all thread handles
Destroy the shutdown event
This approach requires that threads are created with _beginthreadex, so that you are responsible for closing the handles. The benefit of this is that you can wait on threads, even after they've exited (of course an exited thread is already in the signaled state).
As an alternative to what paddy describes another approach would be to instead of having 20 threads that load the comboboxes to just have one thread that loads. By having 20 threads you may not be speeding up things anyway depending on your database library.
Then when that thread is loading periodically (like between each checkbox) check whether user pressed cancel or not, if so then stop processing and exit the thread.
This would make the handling less complicated than managing 20 threads IMHO.
Related
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.
I'm trying to use threading and semaphore to fix a performance problem in my application.
Problem 1:
The user click on some checkbox. Each time a checkbox is clicked, a somewhat intensive saving is done in the database. The users complaint that is was slow. So now, when they click on the checkbox, I just launch a thread that do the saving (without waiting for the thread to finish). That was ok for a short while.
Problem 2:
When the user is fast and unlucky, sometimes the saving in the database crash because at the same time, the other thread is trying to save in the exact same table. So I think that what we need here is semaphore, but I'm not sure.
What I want is this to happen:
User click on checkbox 1
Launch thread 1
User click on checkbox 2
Launch thread 2 (wait for thread 1 to finish)
thread 1 finish
thread 2 finish
Here is my code:
The function we call to launch the thread
bool SampleSO::ExecuteThreadSauvegarde()
{
//Créer le thread
CWinThread* pThreadSauvegarde = AfxBeginThread(ExecuteThreadSauvegarde, this, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
if(pThreadSauvegarde)
{
pThreadSauvegarde->m_bAutoDelete = TRUE;
pThreadSauvegarde->ResumeThread();
}
return true;
}
Then the function who is called by the previous function (static)
UINT SampleSO::ExecuteThreadSauvegarde(LPVOID pParam)
{
SampleSO* pSampleSO = (SampleSO*)pParam;
LONG dwSemCount;
HANDLE hSemaphore = OpenSemaphore( SYNCHRONIZE |SEMAPHORE_MODIFY_STATE, FALSE, _T("Sauvegarde") );
//this is the function that call the saving
pSampleSO->Sauvegarde();
ReleaseSemaphore(hSemaphore, 1, &dwSemCount);
return 1;
}
How can I modify my code so that the critical section is only accessed one thread at the time and that the thread that are waiting for the semaphore go in the critical section as soon as it's released (one at the time).
Thanks!
What you need is not so many threads. Instead, spawn a single worker thread to deal with DB operations. When the user clicks, simply post a message/command via a queue to the worker thread. The worker simply waits for a command, executes it, and goes back to blocking-waiting on the queue. This will require no synchronization beyond thread-safety for the queue itself, which will be trivial because it's single-producer, single-consumer.
Consider the following thread function:
UINT MyClass::threadFunc(LPVOID lParam)
{
// 1. Initialize stuff
// 2. Validate stuff
// 3. Do first task
// 4. Do second task
// 5. Un-initialize everything and return
}
This thread is created by a dialog in my application. This thread will run only once in the dialog's lifetime (it is a worker thread).
On the occurrence of some asynchronous event (maybe the click of a button, some other event being signaled, whatever), I want to notify this thread to return immediately so that my dialog can exit gracefully (after waiting for this thread to terminate). I cannot just exit the dialog because this thread will still be running.
I am relatively new to C++ and this is what I had thought of (pseudocode):
Surround the thread function in a try-catch.
On occurrence of that asynchronous event, throw a thread terminate exception.
This didn't work so I researched a bit and found answers similar to this one. But for some reason, I have a feeling that there is a much easier way to accomplish this. I just wanted some clarification before I go about implementing said idea.
Thanks!
Some searching, I found these:
Windows, Exception Injection: Throwing an Exception in Other Thread, Defines ThreadAbort
Portable, How can I propagate exceptions between threads?, as you mentioned
Basically exactly what the title says. I would like to update the text that a button contains every 1 second when the user presses that particular button. I have noted that when the program doesn't have focus it works alright and the text refreshes correctly but when I am hovering over the program or when I am trying to click on it's menu Windows inform me that the program is unresponsive and asks me if I want it terminated. When the loop finishes the program returns to its normal state. Also any action I might have done (like moving it around or closing it) while it was Sleep()-ing is executed after the loop. Here is a bit of code:
case ID_BUTTON_START:
// Code executed when pressing Start Button.
char startButtonText[30]; // Storing next loop text
for (int i=5; i>0; i--)
{
sprintf(startButtonText, "Starting in ... %d", i);
SendMessage(hwndButtonStart, WM_SETTEXT, 0, (LPARAM)(startButtonText));
Sleep(1000);
}
Is this normal? If not what's causing this?
The WndProc does not process messages asynchronously within an application which means all messages are expected to be handled quickly and a return value delivered immediately. You must not Sleep in the UI thread since it will block other UI events from being processed. Any heavy work or synchronous requests/jobs which are likely to take a long time should be performed in worker threads. There are at least three viable options:
Create a new (worker thread) for the task.
If the task is likely to be done often, use a thread pool instead.
Set and subscribe to timer events.
I think the call to Sleep() might be keeping you from returning from the WndProc, so your application is not processing the incomming events for 5 secs. I suggest you try to subscribe to 5 timer events in 1s, 2s,..., 5s. Like when the timer message is recieved the button text must change. I don't know a way how to do that off the top of my head.
In one C++ application I have a window whose message loop runs in a separate thread because the main thread is busy calculating and rendering a simulation. The window acts as a log window for the simulation. When the simulation throws an exception, the simulation closes and the log window displays the details.
Now the main thread should wait until the log window is closed. Since the message loop runs on a separate thread, I tried to
WaitForSingleObject(logwindow->thread, INFINITE);
from the main thread.
However, this seems to block the message pump and the log window freezes. So how do I correctly wait until a window is closed or a thread ends?
ED: The window is created on the main thread but runs on a different thread. I'll go ahead and change it so it creates on the message loop thread too.
You have a few options.
Run all the UI out of the main thread and get the worker thread to synchronize reporting back to the main thread to display, for example via PostMessage or SendMessage.
Don't wait at all and get the worker thread to post a message to the main thread when the worker is done.
Use MsgWaitForMultipleObjects for your wait.
To elaborate on MsgWaitForMultipleObjects, it's a wait function that can be configured to return when messages arrive in the queue. Thus you can keep your message pump alive whilst also using a blocking wait in between processing queued messages.
In pseudo-code you would write it like this:
do
{
WaitResult = MsgWaitForMultipleObjects(1, hThread, TRUE, INFINITE, QS_ALLEVENTS);
if (WaitResult == MessageArrivedOnQueue)
PumpMessageQueue();
} while (WaitResult != WaitHandlesSignaled)
The fact that the log window is freezing while the main thread is in a blocking wait suggests the worker thread is sending a message to the main thread and then waiting for a reply, but the main thread is already blocked and cannot reply to it. That is a classic deadlock situation for both threads. You should use MsgWaitForMultipleObjects() instead of WaitForSingleObject() in the main thread to detect when new messages need processing while waiting, eg:
do
{
DWORD dwRet = MsgWaitForMultipleObjects(1, &(logwindow->thread), FALSE, INFINITE, QS_ALLINPUT);
if (dwRet == 0xFFFFFFFF) break;
if (dwRet == (WAIT_OBJECT_0 + 1))
{
process messages here...
}
}
while (dwRet != WAIT_OBJECT_0);
I agree with David that you really should be doing all UI work in the main thread and do your calculations in the worker thread, not the other way around.