Как правильно убить поток CWinThread?
{
........
return 0;
}
m_pcFlashThread = ::AfxBeginThread(FlashSysTrayIcon, this, THREAD_PRIORITY_NORMAL);
........
m_pcFlashThread->m_bAutoDelete = TRUE;
int mmm = m_pcFlashThread->ExitInstance(); // убиваем поток
Использую ExitInstance(), но поток не завершается. Функция возвращает не 0.
{
........
return 0;
}
m_pcFlashThread = ::AfxBeginThread(FlashSysTrayIcon, this, THREAD_PRIORITY_NORMAL);
........
m_pcFlashThread->m_bAutoDelete = TRUE;
int mmm = m_pcFlashThread->ExitInstance(); // убиваем поток
при выходе из функции потока, поток завершается автоматически
при выходе из функции потока, поток завершается автоматически
Дело в том, что в функции потока у меня крутится бесконечный цикл. Поток должен гаситься извне.
Дело в том, что в функции потока у меня крутится бесконечный цикл. Поток должен гаситься извне.
Есть функция:
HANDLE hThread,
DWORD dwExitCode);
Unlike ExitThread, which always kills the calling thread, TerminateThread can kill any thread. The hThread parameter identifies the handle of the thread to be terminated. When the thread terminates, its exit code becomes the value you passed as the dwExitCode parameter. Also, the thread's kernel object has its usage count decremented.
NOTE
--------------------------------------------------------------------------------
The TerminateThread function is asynchronous. That is, it tells the system that you want the thread to terminate but the thread is not guaranteed to be killed by the time the function returns. If you need to know for sure that the thread has terminated, you might want to call WaitForSingleObject (described in Chapter 9) or a similar function, passing the handle of the thread.
------------------------------------------------
A well-designed application never uses this function because the thread being terminated receives no notification that it is dying. The thread cannot clean up properly and it cannot prevent itself from being killed.
NOTE
--------------------------------------------------------------------------------
When a thread dies by returning or calling ExitThread, the stack for the thread is destroyed. However, if TerminateThread is used, the system does not destroy the thread's stack until the process that owned the thread terminates. Microsoft purposely implemented TerminateThread in this way. If other still-executing threads were to reference values on the forcibly killed thread's stack, these other threads would raise access violations. By leaving the killed thread's stack in memory, other threads can continue to execute just fine.
In addition, DLLs usually receive notifications when a thread is terminating. If a thread is forcibly killed with TerminateThread, however, the DLLs do not receive this notification, which can prevent proper cleanup. (See Chapter 20 for more information.)
Из книги Д.Рихтера.
Ремарка: поток рекомендуется завершать через выход из его потоковой функции.
Использую ExitInstance(), но поток не завершается. Функция возвращает не 0.
{
........
return 0;
}
m_pcFlashThread = ::AfxBeginThread(FlashSysTrayIcon, this, THREAD_PRIORITY_NORMAL);
........
m_pcFlashThread->m_bAutoDelete = TRUE;
int mmm = m_pcFlashThread->ExitInstance(); // убиваем поток
Можешь использовать Event. Перед запуском Thread создать Event в неактивном состоянии, а в теле Thread поместить вызов ф-ии WaitForSingleObject, по возможности с другим параметром, чем INFINITE.
Но проще всего было бы использовать какую-то
переменную:
STATIC BOOL bQuit = FALSE;
UINT FlashSysTrayIcon(LPVOID pParam) // это - функция потока
{
if(bQuit==TRUE)return 0;
........
return 0;
}
m_pcFlashThread = ::AfxBeginThread(FlashSysTrayIcon, this, THREAD_PRIORITY_NORMAL);
........
bQuit = TRUE;
Если хочешь знать точно, что Thread завершил работу:
DWORD dwWait = WaitForSingleObject(m_pcFlashThread, 1000);
Если dwWait равен 0, то Thread завершился.
STATIC BOOL bQuit = FALSE;
UINT FlashSysTrayIcon(LPVOID pParam) // это - функция потока
{
if(bQuit==TRUE)return 0;
........
return 0;
}
во избежание неприятностей с оптимизатором кода лучше писать volatile BOOL bQuit
во избежание неприятностей с оптимизатором кода лучше писать volatile BOOL bQuit
Да, в данном случае volatile лучше чем static.