Say the main window of a GUI application creates a helper UI thread and the application closes. When and where will the application get a chance to clean up the thread resources? I know that the system automatically clears the resources but that doesn't help application specific resources like files etc.
As a test I had written MessageBox() in the destructors of window objects but they are not called from within the helper threads on closing the application.
It seems the systems simply shuts down the threads, may be via internal TerminateThread or some such call. Is there a way to know when exactly a thread with UI terminates and trap it?
I am using Win32 API not MFC etc.
Pseudocode
OnCreateHelperUI() // called from WndProc under appropriate message
CreateThread(...,UIThread,...)
return
UIThread()
Some auto objects on stack
Some dynamic objects on heap
CreateWindow()
while(GetMessage()){}
delete heap objects
return 0
The destructors of auto and heap objects aren't called.
FYI, waiting on the thread handle doesn't help. It simply lets the threads stick around forcing the user to close them individually. CloseHandle() will lead back to square one.
The thread closes when the thread function returns. The OS cannot do that for you, you must design it in. One good way is to have your main thread WM_CLOSE handler send a signal or message to the secondary thread. The secondary thread cleanly cleans up and returns (running destructors). While this is happening the main thread should be waiting on the thread handle, so it does not shut the app down until the secondary thread has shut down.
Related
The COINIT - an enumeration used to specify whether a windows thread is in a single or multithreaded apartment - documentation (http://msdn.microsoft.com/en-gb/library/windows/desktop/ms678505(v=vs.85).aspx) states that:
The multi-threaded apartment is intended for use by non-GUI threads. Threads in multi-threaded apartments should not perform UI actions. This is because UI threads require a message pump, and COM does not pump messages for threads in a multi-threaded apartment.
Why shouldn't threads in multi threaded apartments perform UI actions? What is wrong with having a message loop in a thread in a multi threaded apartment? Does COM somehow provide an automatic message loop for a thread in a single threaded apartment?
That's a bit backwards, a UI thread primarily requires a message loop so that it can receive notifications from Windows and other processes. A message loop is the universal solution to the producer-consumer problem. With the operating system and other processes producing, the UI thread consuming.
A UI thread uses lots and lots of code that is not thread-safe. This includes major features implemented in COM, like drag+drop, the clipboard, the shell dialogs, ActiveX controls like a browser. And a raft of code that was never made thread-safe because the programmer didn't have to make it so, much easier to write. Those features require an STA thread, in other words a thread that initializes COM by passing COINIT_APARTMENTTHREADED to CoInitializeEx().
That is a promise to COM that the thread will be a good citizen, it is not allowed to make blocking calls and must pump a message loop. It is the message loop that COM uses to marshal a call from a worker thread to the STA thread in order to keep a COM object thread-safe. When all the calls are made from the same thread then there's never a safety issue. The underlying call is SendMessage(), with a ton of plumbing to copy the function arguments from one stack to another. CoInitializeEx() creates a hidden message window owned by the STA thread that processes the message and actually makes the call. Safely.
Is it possible to get notified if a thread had been destroyed? I've already seen such question here:
Notification when a thread is destroyed
The answer was: DLL_THREAD_DETACH, but it won't get called in case of TerminateThread.
So, my question is that, is it possible to detect even the termination? I don't want to prevent it, just get a notification if any of my threads got destroyed. I don't necessarily want to use DllMain, any solution would be great!
I'm working in a DLL, which get's injected into my main application, so I can't use WaitForSingleObject, since it suspends the main executable.
Thank you for each answer.
(P.s.: Just for understanding, my dll works the following way: Main application Loads the dll, on DLL_PROCESS_ATTACH, I open up some threads.)
Edit:
I forgot, I'm using windows & Visual Studio 2013.
Edit 2:
I came to that Disabling thread library calls, is useless. I mean it doesn't work the way I thought :) /I deleted that part, so it won't mislead anyone/
I would suggest having your DLL spawn its own worker thread that can then use WaitForSingleObject() on the handle of the thread that you need to monitor. The handle is signaled when the thread terminated, even when terminated by TerminateThread(). Better would be to use WaitForMultipleObjects() so that your DLL can signal the worker thread when it needs to terminate, such as with CreateEvent() and SetEvent(). That way the worker thread does not need to run a busy loop looking for a termination condition periodically.
I just readed documentation about DllMain():
If you terminate a thread by calling TerminateThread, the DLLs of that
thread do not receive DLL_THREAD_DETACH notifications.
So, in case thread termanatin you will not receive DLL_THREAD_DETACH.
The important think about DLL_THREAD_DETACH is that you will receive this notification in case "A thread is exiting cleanly"
You could run a watcher thread which will monitor all the threads you need and generate "no-more-the-thread" notifications.
Inside my desktop application I have created a simple thread by using _beginthreadex(...). I wonder what happens if my application will be closed (without explicitly closing the thread)? Will all resources inside the thread be cleared automatically? I have doubts.
So I like to end the thread when my application will be closed. I wonder what would be the best practise?
Using _endthreadex is only possible inside(!) the thread and something like TerminateThread(...) does not seems to work (infinite loop). Do you have some advices?
When main exits your other threads will be destroyed.
It's best to have main wait on your other threads, using their handles, and send them a message (using an event, perhaps) to signal them to exit. Main can then signal the event and wait for the other threads to complete what they were doing and exit cleanly. Of course this requires that the threads check the event periodically to see if they need to exit.
When the main thread exits, the app and all of its resources are cleaned up. This will include other threads and their resources.
Also, post the code you have for TerminateThread, because it works.
The tidiest way is to send your thread(s) a message (or otherwise indicate via an event) that the tread should terminate and allow it to free its resources and exit its entry point function.
To close the thread, you need to call CloseHandle() with the handle returned by _beginthreadex.
The thread is part of the process, so when the process terminates it will take the thread with it and the operating system will resume ownership of everything the two own, so all the resources will be released.
Bear in mind that if you have not forewarned the thread that the-end-is-nigh, it may be in the middle of some work when it ends. If it is in the middle of using any system or external resources, they will be released but may be in a funky state (e.g. a file may be partially written, etc).
See also http://www.bogotobogo.com/cplusplus/multithreading_win32A.php
Note: Using CloseHandle() is only for _beginthreadex and not if you are using _beginthread. See http://msdn.microsoft.com/en-us/library/kdzttdcb(v=vs.90).aspx
I have a thread which creates COM objects that use the STA model.
This thread's Run function puts it in an infinite WaitForMultipleObjects.
Is it possible that the infinite WaitForMultipleObjects could prevent other threads from marshaling calls to the COM objects owned by this thread?
Basically, I'm asking if WaitForMultipleObjects would prevent the hidden COM message queue from being pumped.
Yes, problems are possible - see this KB article. Basically if your thread is an STA thread it should not call functions that can block for long periods of time since while the thread is blocked it doesn't pump and dispatch messages and this can prevent proper marshalling functioning.
I understand the problem with just killing the thread directly (via AfxEndThread or other means), and I've seen the examples using CEvent objects to signal the thread and then having the thread clean itself up. The problem I have is that using CEvent to signal the thread seems to require a loop where you check to see if the thread is signaled at the end of the loop. The problem is, my thread doesn't loop. It just runs, and the processing could take a while (which is why I'd like to be able to stop it).
Also, if I were to just kill the thread, I realize that anything I've allocated will not have a chance to clean itself up. It seems to me like any locals I've been using that happen to have put stuff on the heap will also not be able to clean themselves up. Is this the case?
There is no secret magic knowledge here.
Just check the event object periodically throughout the function code, where you deem it is safe to exit.
Does your thread ever exit? If so, you could set an event in the thread at exit and have the main process wait for that event via waitforsingleevent. This is best to do with a timeout so the main process doesn't appear to lockup when it's closing. At the timeout event, kill the thread via AfxKillThread. You'll have to determine what a reasonable timeout is, though.
Since you don't loop in the thread this seems to me to be the only way to do this. Of course, you could something like set a boolean flag in the main process and have the thread periodically check this flag, but then your thread code will be littered with "if(!canRun) return;" type code.
If the thread never exits, then AfxKillThread/AfxTerminateThread is the only way to stop the thread.
Locals would be placed on the stack and, hence, WOULD be freed on forcing the thread shut (I think). Destructors won't get called though and any critical sections the thread holds will not get released.
If the thread is ONLY doing things with simple data types on the stack, however, it IS a safe thing to be doing.