创建一个进程后,会返回一个结构体,OUT出来 ```c++ typedef struct _PROCESS_INFORMATION { HANDLE hProcess; HANDLE hThread; DWORD dwProcessId; DWORD dwThreadId; } PROCESS_INFORMATION, *PPROCESS_INFORMATION, *LPPROCESS_INFORMATION; ``` 父进程于是就有了子进程的进程句柄、线程句柄、进程ID、和线程ID。那么句柄是什么?ID又是什么?它们之间有无联系。 句柄表 什么是内核对象? 像进程、线程、文件、互斥体、事件等在内存中都有一个相对应的结构体,这些结构体由内核负责管理,这样的对象称作内核对象。 内核对象一共有哪些? 如果是CloseHandle能够关闭的句柄就是内核对象。 > The CloseHandle function closes handles to the following objects: > > - Access token > - Communications device > - Console input > - Console screen buffer > - Event > - File > - File mapping > - I/O completion port > - Job > - Mailslot > - Memory resource notification > - Mutex > - Named pipe > - Pipe > - Process > - Semaphore > - Thread > - Transaction > - Waitable timer 如何管理内核对象? 这个进程在内核只有一个EPROCESS,而这个进程又创建了多个内核对象,例如 Process Thread Event File object,那么这么多的内核对象,我们的操作系统是怎么管理的呢? 有人说,返回这个内核结构的地址不就可以了嘛,这里存在的问题是,如果内核地址大于0x7fff ffff,用户访问的内核地址不安全。直接访问内核,如果地址出错,就可能直接蓝屏了。这样就引出了句柄表。 句柄的创造其实是一个防火墙,把用户层和内核层隔离开来,实习安全。 通过句柄对线程进行控制 ```c++ bool CreateChildProcess(TCHAR* szChildProcessName, TCHAR* szCommandline) { STARTUPINFO si; //IN 给子进程附属性,一般全为空 PROCESS_INFORMATION pi; //OUT 创建进程成功后,返回子进程的标识 ZeroMemory(&si, sizeof(si)); ZeroMemory(&pi, sizeof(pi)); if(!CreateProcess( szChildProcessName, //进程对象名称 szCommandline, //命令行参数 NULL, //不继承进程句柄 NULL, //不继承线程句柄 FALSE, //不继承句柄 0, //没有创建标志 NULL, //使用父进程环境变量 NULL, //使用父进程环境变量作为当前目录,可以自己设置目录 &si, //caller &pi //out 创建子进程信息 )) { printf("Last error: %d \n", GetLastError()); } //打印子进程相关信息 printf("进程句柄:%d, 线程句柄:%x, 进程ID: %x, 线程ID: %x", pi.hProcess, pi.hThread, pi.dwProcessId, pi.dwThreadId); //通过子进程句柄对子进程控制 SuspendThread(pi.hThread); //线程假死,僵尸状态 ResumeThread(pi.hThread); //复活线程 //释放子进程句柄 CloseHandle(pi.hProcess); CloseHandle(pi.hThread); return TRUE; //CreateProcess() } int _tmain(int argc, _TCHAR* argv[]) { TCHAR szApplicationName[] = TEXT("c://programe files//internet explorer//iexplor.exe"); TCHAR szCommand[] = TEXT("http://wangyuedong.com"); CreateChildProcess(szApplicationName, szCommand); //getchar(); return 0; } ``` 多进程共享一个内核对象 创建的内核对象是**共享的**。 总结:两种共享内核对象的方案 1、平行进程,另外一个进程通过OpenProcess() 打开另一个进程的内核对象,内核对象计数器++; 2、子进程通过集成来共享父进程的内核对象。