[英]Close Thread Before Exit application
我想在退出主程序之前停止線程。 此代碼正確嗎? (簡化示例)
HANDLE hThread;
BOOL live = TRUE;
DWORD WINAPI Thread ( LPVOID lpParam )
{
..
while(live);
..
}
case WM_DESTROY:
{
live=FALSE;
WaitForSingleObject(hThread, INFINITE);
}
同步線程的最安全方法是使用某些內核對象。 您可以使用CreateEvent
創建“終止”事件,然后在線程回調函數中等待它:
#include <Windows.h>
#include <iostream>
using std::cout;
using std::cerr;
using std::endl;
DWORD WINAPI Callback(LPVOID lpVoid)
{
HANDLE hTerminateEvent = *(reinterpret_cast<HANDLE*>(lpVoid));
bool terminate = false;
while(!terminate)
{
DWORD retVal = WaitForSingleObject(hTerminateEvent, 0);
switch(retVal)
{
case WAIT_OBJECT_0:
cout << "Terminate Event signalled" << endl;
terminate = true;
break;
case WAIT_TIMEOUT:
cout << "Keep running..." << endl;
Sleep(1000);
break;
case WAIT_FAILED:
cerr << "WaitForSingleObject() failed" << endl;
terminate = true;
break;
}
}
return 0;
}
int main()
{
DWORD threadID = 0;
HANDLE hTerminateEvent = CreateEvent(0, FALSE, FALSE, 0);
HANDLE hThread = CreateThread(0, 0, Callback, &hTerminateEvent, 0, &threadID);
// allow some time to thread to live
Sleep(20000);
// set terminate event
if(!SetEvent(hTerminateEvent))
{
cerr << "SetEvent() failed" << endl;
return 1;
}
// wait for thread to terminate
DWORD retVal = WaitForSingleObject(hThread, INFINITE);
switch(retVal)
{
case WAIT_OBJECT_0:
cout << "Thread terminated" << endl;
break;
case WAIT_FAILED:
cerr << "WaitForSingleObject() failed" << endl;
break;
}
CloseHandle(hThread);
CloseHandle(hTerminateEvent);
return 0;
}
輸出:
Keep running...
Keep running...
Keep running...
Keep running...
Keep running...
Keep running...
Keep running...
Keep running...
Keep running...
Keep running...
Keep running...
Keep running...
Keep running...
Keep running...
Keep running...
Keep running...
Keep running...
Keep running...
Keep running...
Keep running...
Terminate Event signalled
Thread terminated
為了確保線程看到live
變化,您需要使live
volatile
:
volatile BOOL live = TRUE;
不,這是不正確的。 您沒有任何東西可以保證線程能夠看到更改。 編譯器可以自由進行優化:
DWORD WINAPI Thread ( LPVOID lpParam )
{
..
while(live);
..
}
至:
DWORD WINAPI Thread ( LPVOID lpParam )
{
..
register bool temp=live;
while(temp);
..
}
那顯然是行不通的。
經驗法則是- 永遠不要在一個線程中訪問變量,而另一個線程可能正在修改它,除非您使用某種特定的機制來確保操作安全。 如果遵循該規則,您將不會遇到麻煩。
void onexxit() {
/* do-it */
}
那atexit( onexxit )
函數呢
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.