今天坐着无聊,突然想到,如果A进程分配足够多的内核对象后,过一段时间A还能分配内核对象吗?,猜想应该是可以的,因为内核对象空间是由内核分配的,
所以做了个小实验:
我们都知道,创建线程内核对象引用计数为2,线程退出减一,closehandle减一,所以不调用closehandle,那么内核对象就会存在,直接用个工具Process Explorer
直接上代码:
static DWORD WINAPI WinMain(LPVOID lp);
DWORD WINAPI CDEMO1Dlg::WinMain(LPVOID lp)
{
return TRUE;
}
CString GetMyLastError()
{
DWORD dwError = ::GetLastError();
HLOCAL hlocal = NULL; // Buffer that gets the error message string
DWORD systemLocale = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
BOOL fOk = FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL, dwError, systemLocale,
(PTSTR) &hlocal, 0, NULL);
CString szErr = _T("");
if (fOk)
{
szErr = (PCTSTR) LocalLock(hlocal);
}
LocalUnlock(hlocal);
LocalFree(hlocal);
return szErr;
}
void CDEMO1Dlg::OnBnClickedButton1()
{
int i=10009;
while (i)
{
HANDLE m_h = CreateThread(NULL, 0, WinMain, this, 0, NULL);
i--;
if (!m_h)
{
CString sz;
sz.Format(L"%d", GetLastError());
AfxMessageBox(sz);
}
}
}
好吧,我很无聊的用了WinMain函数做为线程入口函数,这表明线程函数可以任意命名,
先介绍下ProcessExplorer,
选中Show Lower Pane后,出现Type,Name(下面部分),这就是句柄信息,
选中Demo1.exe
运行上面的代码:
我们发现名称为Thread有一堆了,这都是线程内核对象,最后分配不了了,弹出下面的框;
,这时是不是意味着Demo1.exe进程不能再分配内核对象了?,把代码改下:
void CDEMO1Dlg::OnBnClickedButton1()
{
int i=0;
while (true)
{
HANDLE m_h = CreateThread(NULL, 0, WinMain, this, 0, NULL);
if (!m_h)
{
CString sz;
sz.Format(L"共成功分配了%d个内核对象",i);
AfxMessageBox(sz);
break;
}
i++;
}
}
多次运行后,我们发现,过一段时间Demo1.exe进程还能再分配内核对象了,估计系统从其他地方又挤出分配空间了,没完没了了!