今天坐着无聊,突然想到,如果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进程还能再分配内核对象了,估计系统从其他地方又挤出分配空间了,没完没了了!