How to ensure thread is not terminated before finalizer completes - multithreading

I have an unmanaged class that is running a message loop for a child Win32 window. When the program goes to close, it starts the finalizer for the managed class that holds the unmanaged reference to this class. Because another thread is dependent on this class, I need the finalizer to wait until the message loop thread has completed a loop and exits and terminates. However, the timeout loop I have apparently takes too long for the GC finalizer thread or the main thread terminates destroying the entire process.
Is there a way to tell the GC to not timeout a thread for finalizers? I.E. - I need the finalizer thread to block for a little while in the finalizer so it can complete terminating the message loop thread and then release the unmanaged resource.
Here is my finalizer so you get an idea of what's going on:
PONms::NestedWin32::
!NestedWin32()
{
if (msgLoop->IsAlive)
{
winProcess->EndThread(); // blocks and waits for message loop thread to terminate
// and GC apparently doesn't like this causeing the
// entire process to terminate here.
}
if (childHandle != nullptr)
{
DestroyWindowCore(childHandle);
}
if (winProcess != nullptr)
{
delete winProcess; // memory leak due to resource not being released
}
}
I'm thinking I went about this the wrong way, just expecting the code to behave properly and the finalizer to complete.
Here is the simple method I use to poll the other thread to see if it has terminated:
void PONms::NestedWin32UM::
EndThread()
{
int timeOut = 5000;
threadContinue = false;
SendNotifyMessage(childWin, WM_CLOSE, 0, 0);
while (threadActive && timeOut > 0)
{
POCPP::Threading::SleepThreadOne();
timeOut--;
}
}

int timeOut = 5000;
That is a pretty drastic mismatch with the default CLR policy for the finalizer thread timeout. You've got 2 seconds to get the job done. Roughly 10 billion instructions on a modern processor. We can't see what SleepThreadOne() does, but Sleep(1) doesn't sleep for 1 millisecond. Default sleep granularity is 15.625 msec so you'll end up waiting for as long as 78 seconds.
Technically you can extend the timeout by custom-hosting the CLR, ICLRPolicyManager::SetTimeout() method, OPR_FinalizerRun setting. But, realistically, if you can't hack it with 10 billion instructions then extending it isn't very likely to bring relief.
Debugging this isn't that simple, those 2 seconds are over in a hurry. Look at structural fixes. Don't use a bool to synchronize code, use an event (CreateEvent winapi function). And WaitForSingleObject() with a timeout to wait for it to be set. Use 1000 msec max so you give the finalizer thread enough breathing room. And don't be too nice asking the message loop to quit, WM_CLOSE is far too friendly. Code is apt to respond to it with a "Save changes?" message box, that's a guaranteed fail. Use PostQuitMessage(). Or don't bother at all, programs should terminate through the UI and you seem to need to pull the rug another way.

Related

Disabling a System.Threading.Timer instance while its callback is in progress

I am using two instances of System.Threading.Timer to fire off 2 tasks that are repeated periodically.
My question is: If the timer is disabled but at that point of time this timer is executing its callback on a thread, then will the Main method exit, or will it wait for the executing callbacks to complete?
In the code below, Method1RunCount is synchronized for read and write using lock statement ( this part of code is not shown below). The call back for timer1 increments Method1RunCount by 1 at end of each run.
static void Main(string[] args)
{
TimerCallback callback1 = Method1;
System.Threading.Timer timer1 = new System.Threading.Timer(callback1,null,0, 90000);
TimerCallback callback2 = Method2;
System.Threading.Timer timer2 = new System.Threading.Timer(callback2, null, 0, 60000);
while (true)
{
System.Threading.Thread.Sleep(250);
if (Method1RunCount == 4)
{
//DISABLE the TIMERS
timer1.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
timer2.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
break;
}
}
}
This kind of code tends to work by accident, the period of the timer is large enough to avoid the threading race on the Method1RunCount variable. Make the period smaller and there's a real danger that the main thread won't see the value "4" at all. Odds go down considerably when the processor is heavily loaded and the main thread doesn't get scheduled for while. The timer's callback can then execute more than once while the main thread is waiting for the processor. Completing missing the value getting incremented to 4. Note how the lock statement does not in fact prevent this, it isn't locked by the main thread since it is probably sleeping.
There's also no reasonable guess you can make at how often Method2 runs. Not just because it has a completely different timer period but fundamentally because it isn't synchronized to either the Method1 or the Main method execution at all.
You'd normally increment Method1RunCount at the end of Method1. That doesn't otherwise guarantee that Method1 won't be aborted. It runs on a threadpool thread, they have the Thread.IsBackground property always set to true. So the CLR will readily abort them when the main thread exits. This again tends to not cause a problem by accident.
If it is absolutely essential that Method1 executes exactly 4 times then the simple way to ensure that is to let Method1 do the counting. Calling Timer.Change() inside the method is fine. Use a class like AutoResetEvent to let the main thread know about it. Which now no longer needs the Sleep anymore. You still need a lock to ensure that Method1 cannot be re-entered while it is executing. A good way to know that you are getting thread synchronization wrong is when you see yourself using Thread.Sleep().
From the docs on System.Threading.Timer (http://msdn.microsoft.com/en-us/library/system.threading.timer.aspx):
When a timer is no longer needed, use the Dispose method to free the
resources held by the timer. Note that callbacks can occur after the
Dispose() method overload has been called, because the timer queues
callbacks for execution by thread pool threads. You can use the
Dispose(WaitHandle) method overload to wait until all callbacks have
completed.

Thread scheduling issue with MFC and AfxBeginThread

I'm creating a worker thread in MFC with AfxBeginThread, but the thread is not getting scheduled. Here's the code:
CWinThread* worker = AfxBeginThread(initialUpdateWorkerThread, this);
DWORD dwExitCode = 0;
while(GetExitCodeThread(worker->m_hThread, &dwExitCode))
{
if(dwExitCode != STILL_ACTIVE)
break;
::Sleep(100);
}
When I run this, this loop just livelocks because initialUpdateWorkerThread is never called (I've put break points and message boxes at the top of it) so dwExitCode is always STILL_ACITVE. But if I put in a call to AfxMessageBox before the loop but after AfxBeginThread then the function is called. This makes me think that somehow I'm not calling the right function to get the thread scheduled, but a call to AfxMessageBox causes it to get scheduled.
How can I force the thread to be scheduled? I would think sleep would do that, but in this case it doesn't seem to.
Your worker thread is probably trying to send your main thread a message, but since you aren't processing messages on on the main thread, the worker thread simply waits. You can confirm this by simply breaking into the debugger to see what the worker thread is doing.

winapi threads take time to initialise before message passing works?

I have a main program that creates the threads in order:
ThreadB then
ThreadA (which is passed ThreadB's ID)
using the CreateThread function.
Thread A sends a message to Thread B using PostThreadMessage.
B gets the message using GetMessage.
The problem I am having is that PostThreadMessage blocks randomly the first time it is called and never returns, some times the program funs fine, other times I run the program and it blocks with 0 CPU usage at the first postthreadmessage. However if I add Sleep(10) to ThreadA before the first PostThreadMessage, I never seem to encouter this problem.
What am I missing about the timing of threads and messages?
You cannot send a message to a thread until it has a message queue. Message queues are not created until that thread calls a function such as GetMessage or PeekMessage. What your sleep does is delay the sending thread long enough that the receiving thread has called GetMessage and set up its message queue.
Incidentally, I strongly recommend against using PostThreadMessage as the messages can get lost. It is better to create a message-only window (with a parent of HWND_MESSAGE) on the receiving thread and send messages to that instead.
To add to Anthony Williams correct answer, the code I use to deal with this looks like. I have a class similar to MyThread...
void MyThread::Start()
{
m_hResumeMain = CreateEvent(NULL,FALSE,FALSE,NULL);
m_hThread = CreateThread(NULL,0,ThreadProc,this,0,&m_dwThreadId);
WaitForSingleObject(m_hResumeMain,INFINITE);
CloseHandle(m_hResumeMain);
m_hResumeMain=0;
}
DWORD MyThread::ThreadProc(LPVOID pv)
{
MyThread* self = (MyThread*)pv;
return self->ThreadProc();
}
DWORD MyThread::ThreadProc()
{
MSG msg;
// Create the thread message queue
PeekMessage(&msg,0,0,0,PM_NOREMOVE);
// Resume the main thread
SetEvent(m_hResumeMain);
while(GetMessage(&msg,0,0,0)>0){
if(msg.hwnd){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else {
DoThreadMessage(&msg);
}
}
return 0;
}
The crux of the issue is you ultimately cannot rely on a Sleep to guarantee that the worker thread is sufficiently initialized. Plus, in general there is usually some mimimal amount of work a worker thread needs to have done before the launching thread should be allowed to resume. So create an event object before creating the thread, wait for it on the main thread and signal it on the worker thread once the initialization is done.

When myThread.Start(...) is called, do we have the assurance that the thread is started?

When myThread.Start(...) is called, do we have the assurance that the thread is started? The MSDN documentation isn't really specific about that. It says that the status of is changed to Running.
I am asking because I've seen a couple of times the following code. It creates a thread, starts it and then loop until the status become Running. Is that necessary to loop?
Thread t = new Thread(new ParameterizedThreadStart(data));
t.Start(data);
while (t.ThreadState != System.Threading.ThreadState.Running &&
t.ThreadState != System.Threading.ThreadState.WaitSleepJoin)
{
Thread.Sleep(10);
}
Thanks!
If you're set on not allowing your loop to continue until the thread has "started", then it will depend on what exactly you mean by "started". Does that mean that the thread has been created by the OS and signaled to run, but not necessarily that it's done anything yet? Does that mean that it's executed one or more operations?
While it's likely fine, your loop isn't bulletproof, since it's theoretically possible that the entire thread executes between the time you call Start and when you check the ThreadState; it's also not a good idea to check the property directly twice.
If you want to stick with checking the state, something like this would/could be more reliable:
ThreadState state = t.ThreadState;
while(state != ThreadState.Runnung && state != ThreadState.WaitSleepJoin)
{
Thread.Sleep(10:
state = t.ThreadState;
}
However, this is still subject to the possibility of the thread starting, running, then stopping before you even get the chance to check. Yes, you could expand the scope of the if statement to include other states, but I would recommend using a WaitHandle to signal when the thread "starts".
ManualResetEvent signal;
void foo()
{
Thread t = new Thread(new ParameterizedThreadStart(ThreadMethod));
signal = new ManualResetEvent();
t.Start(data);
signal.WaitOne();
/* code to execute after the thread has "started" */
}
void ThreadMethod(object foo)
{
signal.Set();
/* do your work */
}
You still have the possiblity of the thread ending before you check, but you're guaranteed to have that WaitHandle set once the thread starts. The call to WaitOne will block indefinitely until Set has been called on the WaitHandle.
Guess it depends on what you are doing after the loop. If whatever comes after it critically dependant on the thread running then checking is not a bad idea. Personnally I'd use a ManualResetEvent or something similiar that was set by the Thread rather than checking the ThreadStatus
No. Thread.Start causes a "thread to be scheduled for execution". It will start, but it may take a (short) period of time before the code within your delegate actually runs. In fact, the code above doesn't do what (I suspect) the author intended, either. Setting the thread's threadstate to ThreadState.Running (which does happen in Thread.Start) just makes sure it's scheduled to run -- but the ThreadState can be "Running" before the delegate is actually executing.
As John Bergess suggested, using a ManualResetEvent to notify the main thread that the thread is running is a much better option than sleeping and checking the thread's state.

How to wait in the main thread until all worker threads have completed in Qt?

I have designed an application which is running 20 instance of a thread.
for(int i = 0;i<20;i++)
{
threadObj[i].start();
}
How can I wait in the main thread until those 20 threads finish?
You need to use QThread::wait().
bool QThread::wait ( unsigned long time = ULONG_MAX )
Blocks the thread until either of
these conditions is met:
The thread associated with this
QThread object has finished execution (i.e. when it returns from
run()). This function will return true if the thread has finished. It
also returns true if the thread has
not been started yet.
time milliseconds has elapsed. If time is
ULONG_MAX (the default), then the wait
till never timeout (the thread must
return from run()). This function
will return false if the wait timed
out.
This provides similar functionality to
the POSIX pthread_join() function.
Just loop over the threads and call wait() for each one.
for(int i = 0;i < 20;i++)
{
threadObj[i].wait();
}
If you want to let the main loop run while you're waiting. (E.g. to process events and avoid rendering the application unresponsible.) You can use the signals & slots of the threads. QThread's got a finished() singal which you can connect to a slot that remembers which threads have finished yet.
You can also use QWaitCondition
What Georg has said is correct. Also remember you can call signal slot from across threads. So you can have your threads emit a signal to you upon completion. SO you can keep track of no of threads that have completed their tasks/have exited. This could be useful if you don't want your Main thread to go in a blocking call wait.

Resources