我想在退出主程序之前停止线程。这段代码正确吗?(简化示例)
HANDLE hThread;
BOOL live = TRUE;
DWORD WINAPI Thread ( LPVOID lpParam )
{
..
while(live);
..
}
case WM_DESTROY:
{
live=FALSE;
WaitForSingleObject(hThread, INFINITE);
}
我想在退出主程序之前停止线程。这段代码正确吗?(简化示例)
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 )
功能呢