Win32、MFC:结束线程
Win32, MFC: Ending threads
我有一个 DLL,它有一个基于 class 的 CWinThread,叫做 CWork。
我使用 AfxBeginThread 创建它。
在这个 class 中,我定义了一个无限循环并执行特定任务的过程。这个过程将自己作为一个线程使用。我也使用 AfxBeginThread 创建它。
现在,当我的 DLL 退出时,我想结束线程。这是因为我在退出时崩溃了,我相信这就是原因。
此外,还有
伪代码示例:
class主线
Cmain::Cmain(){
pMyThread = AfxBeginThread(CWork - a CWinThread based Class);
}
UINT HandleNextVTSConnectionCommandProc(LPVOID pParam);
class CWork
CWork:CWork(){
AfxBeginThread(HandleNextVTSConnectionCommandProc, this);
}
UINT HandleNextVTSConnectionCommandProc(LPVOID pParam){
while(true){
dosomething();
sleep(2000);
}
}
我的问题是,结束这 2 个线程的正确方法是什么?
谢谢!
一般来说,结束线程的正确方法是要求它完成,然后等待它完成。因此,在 Windows 上,您可能会发出一个事件信号,要求线程完成,然后等待线程 HANDLE。强行终止一个线程几乎总是一个错误的想法,它会回来困扰你。
创建一个在线程句柄上调用 CreateEvent that is initially non-signaled. When your application terminates, signal this event (SetEvent) and wait for the thread to terminate (WaitForSingleObject 的事件。
在线程函数中 HandleNextVTSConnectionCommandProc
将 while(true)
循环替换为
while(WaitForSingleObject(hEvent, 0) != WAIT_OBJECT_0)
执行上述操作允许您向线程发出信号以终止您的应用程序。线程终止,当它从它的线程过程 returns 时。
设置一个标志而不是使用 while(true) 来告诉您的线程何时应该结束。您也可以使用事件。
你还应该在退出之前等待你的线程完成,所以你应该使用(在主代码中,一旦你发出线程结束的信号):
WaitForSingleObject(thread_handle)
像这样的事情应该让你开始:
HANDLE g_hThreadExitRequest = NULL;
UINT __cdecl ThreadFunction(LPVOID pParam)
{
AllocConsole();
HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
for (int i=1; true; ++i)
{
CStringA count;
count.Format("%d\n", i);
WriteFile(hCon, (LPCSTR)count, count.GetLength(), NULL, NULL);
if (WaitForSingleObject(g_hThreadExitRequest, 1000) == WAIT_OBJECT_0)
break;
}
// We can do any thread specific cleanup here.
FreeConsole();
return 0;
}
void Go()
{
// Create the event we use the request the thread exit.
g_hThreadExitRequest = CreateEvent(
NULL, // LPSECURITY_ATTRIBUTES lpEventAttributes
TRUE, // BOOL bManualReset
FALSE, // BOOL bInitialState
NULL // LPCTSTR lpName
);
// We create the thread suspended so we can mess with the returned CWinThread without
// MFC auto deleting it when the thread finishes.
CWinThread *pThread = AfxBeginThread(
&ThreadFunction, // AFX_THREADPROC pfnThreadProc
NULL, // LPVOID pParam
THREAD_PRIORITY_NORMAL, // int nPriority
0, // UINT nStackSize
CREATE_SUSPENDED , // DWORD dwCreateFlags
NULL // LPSECURITY_ATTRIBUTES lpSecurityAttrs
);
// Turn off MFC's auto delete "feature".
pThread->m_bAutoDelete = FALSE;
// Start the thread running.
pThread->ResumeThread();
// Wait 30 seconds.
Sleep(30*1000);
// Signal the thread to exit and wait for it to do so.
SetEvent(g_hThreadExitRequest);
WaitForSingleObject(pThread->m_hThread, INFINITE);
// Delete the CWinTread object since we turned off auto delete.
delete pThread;
// We're finished with the event.
CloseHandle(g_hThreadExitRequest);
g_hThreadExitRequest = NULL;
}
我有一个 DLL,它有一个基于 class 的 CWinThread,叫做 CWork。 我使用 AfxBeginThread 创建它。
在这个 class 中,我定义了一个无限循环并执行特定任务的过程。这个过程将自己作为一个线程使用。我也使用 AfxBeginThread 创建它。
现在,当我的 DLL 退出时,我想结束线程。这是因为我在退出时崩溃了,我相信这就是原因。
此外,还有
伪代码示例:
class主线
Cmain::Cmain(){
pMyThread = AfxBeginThread(CWork - a CWinThread based Class);
}
UINT HandleNextVTSConnectionCommandProc(LPVOID pParam);
class CWork
CWork:CWork(){
AfxBeginThread(HandleNextVTSConnectionCommandProc, this);
}
UINT HandleNextVTSConnectionCommandProc(LPVOID pParam){
while(true){
dosomething();
sleep(2000);
}
}
我的问题是,结束这 2 个线程的正确方法是什么?
谢谢!
一般来说,结束线程的正确方法是要求它完成,然后等待它完成。因此,在 Windows 上,您可能会发出一个事件信号,要求线程完成,然后等待线程 HANDLE。强行终止一个线程几乎总是一个错误的想法,它会回来困扰你。
创建一个在线程句柄上调用 CreateEvent that is initially non-signaled. When your application terminates, signal this event (SetEvent) and wait for the thread to terminate (WaitForSingleObject 的事件。
在线程函数中 HandleNextVTSConnectionCommandProc
将 while(true)
循环替换为
while(WaitForSingleObject(hEvent, 0) != WAIT_OBJECT_0)
执行上述操作允许您向线程发出信号以终止您的应用程序。线程终止,当它从它的线程过程 returns 时。
设置一个标志而不是使用 while(true) 来告诉您的线程何时应该结束。您也可以使用事件。
你还应该在退出之前等待你的线程完成,所以你应该使用(在主代码中,一旦你发出线程结束的信号):
WaitForSingleObject(thread_handle)
像这样的事情应该让你开始:
HANDLE g_hThreadExitRequest = NULL;
UINT __cdecl ThreadFunction(LPVOID pParam)
{
AllocConsole();
HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
for (int i=1; true; ++i)
{
CStringA count;
count.Format("%d\n", i);
WriteFile(hCon, (LPCSTR)count, count.GetLength(), NULL, NULL);
if (WaitForSingleObject(g_hThreadExitRequest, 1000) == WAIT_OBJECT_0)
break;
}
// We can do any thread specific cleanup here.
FreeConsole();
return 0;
}
void Go()
{
// Create the event we use the request the thread exit.
g_hThreadExitRequest = CreateEvent(
NULL, // LPSECURITY_ATTRIBUTES lpEventAttributes
TRUE, // BOOL bManualReset
FALSE, // BOOL bInitialState
NULL // LPCTSTR lpName
);
// We create the thread suspended so we can mess with the returned CWinThread without
// MFC auto deleting it when the thread finishes.
CWinThread *pThread = AfxBeginThread(
&ThreadFunction, // AFX_THREADPROC pfnThreadProc
NULL, // LPVOID pParam
THREAD_PRIORITY_NORMAL, // int nPriority
0, // UINT nStackSize
CREATE_SUSPENDED , // DWORD dwCreateFlags
NULL // LPSECURITY_ATTRIBUTES lpSecurityAttrs
);
// Turn off MFC's auto delete "feature".
pThread->m_bAutoDelete = FALSE;
// Start the thread running.
pThread->ResumeThread();
// Wait 30 seconds.
Sleep(30*1000);
// Signal the thread to exit and wait for it to do so.
SetEvent(g_hThreadExitRequest);
WaitForSingleObject(pThread->m_hThread, INFINITE);
// Delete the CWinTread object since we turned off auto delete.
delete pThread;
// We're finished with the event.
CloseHandle(g_hThreadExitRequest);
g_hThreadExitRequest = NULL;
}