我想在退出主程序之前停止线程。这段代码是否正确? (简化示例)
HANDLE hThread;
BOOL live = TRUE;
DWORD WINAPI Thread ( LPVOID lpParam )
{
..
while(live);
..
}
case WM_DESTROY:
{
live=FALSE;
WaitForSingleObject(hThread, INFINITE);
}
答案 0 :(得分:3)
同步线程最安全的方法是使用一些内核对象。在您的情况下,您可以使用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
答案 1 :(得分:2)
为了确保线程看到对live
所做的更改,您需要live
volatile
:
volatile BOOL live = TRUE;
答案 2 :(得分:0)
不,这不对。你没有任何东西可以保证线程看到变化。编译器可以自由优化:
DWORD WINAPI Thread ( LPVOID lpParam )
{
..
while(live);
..
}
为:
DWORD WINAPI Thread ( LPVOID lpParam )
{
..
register bool temp=live;
while(temp);
..
}
这显然不起作用。
经验法则是 - 从不访问一个线程中的变量,而另一个线程可能正在修改它,除非您使用某种特定机制来确保操作是安全的。如果你遵守这条规则,你就可以避免麻烦了。
答案 3 :(得分:0)
void onexxit() {
/* do-it */
}
atexit( onexxit )
功能