VS2013, C++
I just release dll application. One of dll app function run thread by _beginthread.
In normal software flow I use mutex and control threads. Before unregister dll from main application I wait for thread terminating and close handlers.
However there is one case that main application could close without release resources in correct way I mean without waiting for child thread terminating and without close of handlers.
Is there any risk if main application force exit? Is there any risk if I run application and threads again after exit?
Is there any risk for OS? Are all threads terminating after main exit?
I know that it is "dirty" solution but for some reason I can’t change that.
Thank you in advance for advices.
According to Raymond Chen - in Windows systems - if the main thread terminates, your application hangs while all your threads end. This means, no your solution will not work, your thread will freeze your application in the closing state. Also even if your thread would be forcefully terminated on exit, it would not be uninitialized, and - since we are talking about MFC threads here - it would cause your application to leak resources, so pretty please don't do that!
Is there any risk if main application force exit?
Yes! Since thread can have started consistence-sensitive processes.
Is there any risk if I run application and threads again after exit?
Yes! May be previous shutdown crushed the data structure and now you cannot even load data correctly
Is there any risk for OS?
It depends on your business. May be you create a soft for disk-optimization and you are moving clusters while emergency shutdown?
Are all threads terminating after main exit?
Yes! You need foreseen special "join" code that waits accomplishment of threads.
I would say, the behavior is undefined. Too many things may happen, when the application is terminated without having the chance to clean up.
This SO question may give some ideas.
This MS article describes TerminateThread function and also lists some implication of unexpectedly terminating the threads (which is probably happened on calling exit):
If the target thread owns a critical section, the critical section
will not be released.
If the target thread is allocating memory from the heap, the heap lock will not be released.
If the target thread is executing certain kernel32 calls when it is terminated, the kernel32 state for the thread's process could be
inconsistent.
If the target thread is manipulating the global state of a shared DLL, the state of the DLL could be destroyed, affecting other users
of the DLL.
So looks like there is a risk even for the OS
kernel32 state for the thread's process could be inconsistent
Related
I stucked into a problem with threads syncronization and critical sections on Windows 10.
Application will crash in this case:
Application has two threads.
Thread 1 calls EnterCriticalSection with object m_CS
Thread 2 then attempts to enter the same critical section
Thread 1 terminates Thread 2 using TerminateThread
Thread 1 calls LeaveCriticalSection
In previous Windows versions which I was able to test (7, 8, 8.1) this works properly. Thread 2 terminates, and Thread 1 leaves the critical section without exception.
On Windows 10, when Thread 1 leaves the critical section, application crashes with Access Violation. It only happens when another thread was terminated while waiting on EnterCriticalThread.
Looking at the stack trace it looks this (latest frame at the top):
RtlpWakeByAddress
RtlpUnWaitCriticalSection
RtlLeaveCriticalSection
I spent so much time on debugging this issue. In my case m_CS is totally fine when LeaveCriticalSection was called. I debugged and spent some time to analyze disassembled code of ntdll.dll functions. Seems like object corrupts somewhere during execution of RtlpUnWaitCriticalSection and then passed to RtlpWakeByAddress when crash occurs. Basicly ntdll.dll was able to modify CRITICAL_SECTION object's properties such as lock count in RtlLeaveCriticalSection.
From the web I didn't find any answer on this or statement what changed in Windows 10. Only thread on reddit and ~1800 crash reports for Mozilla Firefox with same call stack in the last month. I contacted with author of post on reddit and he was not able to fix this thus far.
So anybody dealed with this issue and may be have a fix for it or advices? As a solution right now I only see to rethink usage of WinAPI TerminateThread and try to avoid it as much as possible. Another way probably to do a code refactoring and think on application's architecture.
Any response appreciated.
Thanks in advance
Implementation of CRITICAL_SECTION very volatile from version to version. when in last Windows version thread begin wait on CRITICAL_SECTION he call WaitOnAddress function. ok, really it ntdll internal implementation - RtlpWaitOnAddress, but this not change gist. this function internal call RtlpAddWaitBlockToWaitList - and here the key point - WaitBlock is allocated on thread stack and pointer to this wait block is added to List. then when owner of CRITICAL_SECTION leave he call WakeByAddressSingle (really it internal implementation RtlpWakeByAddress) and this function pop the first WaitBlock from List, extract thread Id from it and call NtAlertThreadByThreadId(new api from win 8.1) - for awaken some thread waited in EnterCriticalSection. but when you terminated thread, waited in EnterCriticalSection - his stack is deallocated. so address of WaitBlock block become invalid. so thread which called RtlpWakeByAddress (as part of LeaveCriticalSection) got access violation when try read thread Id from WaitBlock (died thread stack).
conclusion - if you call TerminatedThread - process already become in unstable state, bug can be at any time and any point. so - not call this function, especially from self process.
Thread 1 terminates Thread 2 using TerminateThread
Don't do that. It may look like it works on other windows versions, but there's no way for you to know for sure what side-effects are occurring and hiding from you.
From https://msdn.microsoft.com/en-us/library/windows/desktop/ms686717(v=vs.85).aspx
TerminateThread is a dangerous function that should only be used in
the most extreme cases. You should call TerminateThread only if you
know exactly what the target thread is doing, and you control all of
the code that the target thread could possibly be running at the time
of the termination. For example, TerminateThread can result in the
following problems:
If the target thread owns a critical section, the critical section will not be released.
If the target thread is allocating memory from the heap, the heap lock will not be released.
If the target thread is executing certain kernel32 calls when it is terminated, the kernel32 state for the thread's process could be
inconsistent.
If the target thread is manipulating the global state of a shared DLL, the state of the DLL could be destroyed, affecting other users of
the DLL.
What you should do is communicate with thread 2 and let thread 2 shut itself down correctly and safely.
I would change the code of thread 2 to use TryEnterCriticalSection
if(!TryEnterCriticalSection(&m_CS)) {
return 0; // Terminate thread
}
//code
LeaveCriticalSection(&m_CS);
This has the advantage that thread 2 is not waiting on the critical section, and it can terminate itself properly. It is generally not advisable to use TerminateThread, as already mentioned by others in the comments.
Yes, I can confirm this behavior and spent more than 3 days for finding a memoryleak in our code what distroys my CRITICAL_SECTION. The problem was an old call of TerminateThread. The program worked nice, but now on Windows10 we had apparently occuring access violations in EnterCriticalSection or LeaveCriticalSection.
Thank you so much, this made my day.
In my application a thread runs while(1){} in it so thread terminates when my app is terminated by user.
Is it safe to do like this? I am using while(1){} because my app continuously monitors devices on system.
After some time I am getting "(R6016) not enough space for thread data" on ffmpeg.
I read this but did not get solution of my problem:
http://support.microsoft.com/kb/126709
Thread description:
Thread uses ffmpeg and handle utility (http://technet.microsoft.com/en-us/sysinternals/bb896655.aspx). within while(1){} loop.
ffmpeg and handle is running through QProcess which I am deleting after process ends.
while(1){} loop waits for 5 seconds using
msleep(5000).
This is not safe.
Change while (1) to while (!stopCondition) and have stopCondition change to TRUE when exiting. The main thread should wait for all other thread to finish before exiting.
Note: stopCondition is defined as volatile int stopCondition.
When the main thread exists, a cleanup process starts:
- global destructors are called (C++).
- C runtime library starts to shut down, releasing all memory allocated with malloc, unloading dynamic libraries and other resources.
A thread that depends on the C runtime being functional will crash or if it runs code from a shared/dynamic libray. If that thread was doing something important like writing to a file, the file will be corrupt. Maybe in your case things are not so bad, but seeing an application crash doesn't looks good to say the least.
This is not the full story, but I think it makes my point.
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
If I terminate a thread on Windows using the TerminateThread function, is that thread actually terminated once the function returns or is termination asychnronous?
Define "actually terminated". The documentation says the thread can not execute any more user-mode code, so effectively: yes, it is terminated, nothing of your code is going to be executed by that thread any more.
If you "WaitForSingleObject" on it right after terminating, I guess there could still be some slight delay because of cleanup that Windows is doing.
By the way: TerminateThread is the worst way of ending a thread. Try using some other means of synchronization, like a global variable that tells the thread to stop, or an event for example.
Terminating a thread is akin to killing a process, only on a per-thread level. It may in fact be implemented by raising an (uncatchable) signal in the targeted thread.
The result is essentially the same: Your program is not in any particular, predictable state. There's not much you can do with the dead thread. The control flow of your program becomes generally indeterminate, and thus it is extremely hard to reason about your program's behaviour in the presence of thread termination.
Basically, unless your thread is doing something extremely narrow, specific and restricted (e.g. increment an atomic counter once every second), there's no good model for the need to terminate a thread, and for the state of the program after the thread termination.
Don't do it. Design your threads so that you can communicate with them and so that their entry functions can return. Design your program so that you can always join all threads eventually and account for everything.
It is a synchronous call. That does not mean that it necessarily returns quickly - there may be some blocking involved if the OS has to resort to using its inter-core driver to stop the thread, (ie. it's actually running on a different core than the thread requesting the termination).
There are issues with calling TerminateThread from user code during an app run, (as distinct from the kernel using it during app/process termination), as clearly posted by others.
I try very hard to never terminate threads at all during an app run, with TerminateThread or by any other means. App-lifetime threads and thread pools often do not require any explicit termination before the OS destroys them on app close.
Is it real that the TerminateProcess function in Windows could hang because the threads inside the process were stuck in a deadlock?
Example: Process A is running under Process B's control, now Process A gets into a deadlock and Process B detects this and decides to 'Kill' process A using TerminateProcess.
Would it be successful in killing the hung Process A?
Yes, all kernel objects held by the process will be released, including locks.
The main problem with TerminateProcess is that the process has no say in the matter: if it's holding on to any global state (files, shared memory, etc) then you have no guarantee those things are in a consistent state after the process is terminated.
Yes. So long as you have the right permissions, TerminateProcess will kill the other process dead, regardless of how well hung it is.
TerminateProcess will kill each thread (as if TerminateThread had been used on each and every thread in the process).
But it won't kill threads that are stuck in the kernel (e.g. due to device driver bug).