创建一个进程后,会返回一个结构体,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、子进程通过集成来共享父进程的内核对象。