线程的退出方法有:TerminateThread、ExitThread等API函数。但是它们都不是优雅的退出,容易导致线程的内存泄露。我个人比较喜欢采用全局变量控制各子线程退出的方法。示例代码如下:(在VS2008编码器上运行通过)
#include "stdafx.h"
#include <windows.h>
#include <process.h>
#include <assert.h>
// 控制子线程退出的全局变量
volatile bool gbExitThread = false;
// 开启子线程时,传递参数的同步变量
HANDLE ghDataEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
// 子线程。打印线程运行信息
UINT WINAPI SubThread(void* ptr)
{
int nThreadID = *((int*)ptr);
nThreadID++;
SetEvent(ghDataEvent);
printf("%d线程启动/n", nThreadID);
int i = 0;
while(!gbExitThread)
{
printf("%d: %d/n", nThreadID, i++);
Sleep(10000);
}
printf("%d线程退出/n", nThreadID);
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
// 开启的子线程数量,10000个!
int nThreadCount = 10000;
HANDLE* phaThread = new HANDLE[nThreadCount];
int nErr = 0;
for(int i = 0; i < nThreadCount; i++)
{
// 默认情况下,线程的栈空间大小为1M,若电脑的物理内存为2G,则最多能开启2048个线程;
// 现修改为128K,则最多能开启2048*1024/128 == 16384个线程
// 注意initflag参数为STACK_SIZE_PARAM_IS_A_RESERVATION
phaThread[i] = (HANDLE)_beginthreadex(NULL, 128*1024, SubThread, &i, STACK_SIZE_PARAM_IS_A_RESERVATION, NULL);
if(phaThread[i] == 0)
{
nErr = GetLastError();
if(nErr == 8)
{
printf("开启线程失败,存储空间不足!/n");
}
else
{
printf("开启线程失败,错误号%d/n", nErr);
}
break;
}
// 等待子线程成功开启的同步事件
WaitForSingleObject(ghDataEvent, INFINITE);
}
// 控制子线程的退出。按'q'键退出所有的子线程。
int ch = 0;
while(ch =getchar())
{
if(ch == 'q')
{
gbExitThread = true;
break;
}
}
DWORD ulRes = WAIT_TIMEOUT;
// 等待所有子线程的退出,支持 > MAXIMUM_WAIT_OBJECTS个线程
int nStt = 0;
while(nThreadCount > 0)
{
if(nThreadCount > MAXIMUM_WAIT_OBJECTS)
{
ulRes = WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, phaThread+nStt, TRUE, 1000*60);
}
else
{
ulRes = WaitForMultipleObjects(nThreadCount, phaThread+nStt, TRUE, 1000*60);
}
assert(ulRes != WAIT_TIMEOUT);
nThreadCount -= MAXIMUM_WAIT_OBJECTS;
nStt += MAXIMUM_WAIT_OBJECTS;
}
return 0;
}