Click to See Complete Forum and Search --> : Windows SDK: How to check if a thread is still active?


ovidiucucu
July 7th, 2011, 09:28 AM
Q: How to check if a thread is still active?

A: One often used method is to call GetExitCodeThread function, then see if returns STILL_ACTIVE value.

Example
DWORD CheckIfThreadIsStillActive(DWORD dwThreadID, BOOL& bIsActive)
{
bIsActive = FALSE;
HANDLE hThread = ::OpenThread(THREAD_QUERY_INFORMATION, FALSE, dwThreadID);
if(NULL == hThread)
return ::GetLastError();

DWORD dwExitCode = 0;
BOOL bRet = ::GetExitCodeThread(hThread, &dwExitCode);
::CloseHandle(hThread);
if(! bRet)
return ::GetLastError();

if(STILL_ACTIVE == dwExitCode)
bIsActive = TRUE;

return NO_ERROR;
}
This method is generally OK but has a little disadvantage: it is possible that thread has been terminated returning exactly the STILL_ACTIVE value.
That may lead in troubles because of the false assumption.

Other more reliable way is to call WaitForSingleObject function, passing 0 (zero) value for time-out parameter.
In this case, WaitForSingleObject does not enter in wait state and returns immediately.
If the returned value is WAIT_TIMEOUT, then the thread is still active.

Example
DWORD CheckIfThreadIsStillActive(DWORD dwThreadID, BOOL& bIsActive)
{
bIsActive = FALSE;
HANDLE hThread = ::OpenThread(SYNCHRONIZE, FALSE, dwThreadID);
if(NULL == hThread)
return ::GetLastError();

DWORD dwRet = ::WaitForSingleObject(hThread, 0);
::CloseHandle(hThread);
if(WAIT_FAILED == dwRet)
return ::GetLastError();

if(WAIT_TIMEOUT == dwRet)
bIsActive = TRUE;

return NO_ERROR;
}

Notes

For GetExitCodeThread, the thread handle must have THREAD_QUERY_INFORMATION access right;
For WaitForSingleObject, the thread handle must have SYNCHRONIZE access right.


Resources

[MSDN] GetExitCodeThread Function (http://msdn.microsoft.com/en-us/library/ms683190(VS.85).aspx)
[MSDN] WaitForSingleObject Function (http://msdn.microsoft.com/en-us/library/ms687032(v=VS.85).aspx)