PROCESS_INFORMATION结构体说明

​​​​​​PROCESS_INFORMATION结构体如下:
typedef struct _PROCESS_INFORMATION {

HANDLE hProcess; //存放每个对象的与进程相关的句柄

HANDLE hThread; //返回的线程句柄。

DWORD dwProcessId; //用来存放进程ID号

DWORD dwThreadId; //用来存放线程ID号

} PROCESS_INFORMATION, *PPROCESS_INFORMATION, *LPPROCESS_INFORMATION;

调用Createprocess ()函数后,会自动地对该结构进行填充.

        如前所述,创建新进程可使系统建立一个进程内核对象和一个线程内核对象。在创建进程的时候,系统为每个对象赋予一个初始使用计数值1 。然后,在createProcess返回之前,该函数打开进程对象和线程对象,并将每个对象的与进程相关的句柄放入 PROCESS_INFORMATION结构的hProcess 和hThread 成员中。当CreateProcess 在内部打开这些对象时,每个对象的使用计数就变为2 。
        这意味着在系统能够释放进程对象前,该进程必须终止运行(将使用计数递减为1),并且父进程必须调用CloseHandle (再将使用计数递减1,使之变为0)。同样,若要释放线程对象,该线程必须终止运行,父进程必须关闭线程对象的句柄(关于释放线程对象的详细说明,请参见本章后面“子进程”一节的内容)

        注意必须关闭子进程和它的主线程的句柄,以避免在应用程序运行时泄漏资源。当然,当进程终止运行时,系统会自动消除这些泄漏现象,但是,当进程不再需要访问子进程和它的线程时,编写得较好的软件能够显式关闭这些句柄(通过调用CloseHandle 函数来关闭)。不能关闭这些句柄是开发人员最常犯的错误之一。

        由于某些原因,许多开发人员认为,关闭进程或线程的句柄,会促使系统撤消该进程或线程。实际情况并非如此。关闭句柄只是告诉系统,你对进程或线程的统计数据不感兴趣。进程或线程将继续运行,直到它自己终止运行。

        当进程内核对象创建后,系统赋予该对象一个独一无二的标识号,系统中的其他任何进程内核对象都不能使用这个相同的ID号。线程内核对象的情况也一样。当一个线程内核对象创建时,该对象被赋予一个独一无二的、系统范围的I D号。进程I D和线程I D共享相同的号码池。这意味着进程和线程不可能拥有相同的I D 。另外,对象决不会被赋予0 作为其I D。在CreateProcess 返回之前,它要用这些I D填入PROCESS_INFORMATION 结构的dwProcessId 和dwThreadId 成员中。I D使你能够非常容易地识别系统中的进程和线程。一些实用工具(如Task Manager)对I D使用得最多,而高效率的应用程序则使用得很少。由于这个原因,大多数应用程序完全忽略ID。

        如果应用程序使用I D来跟踪进程和线程,必须懂得系统会立即复用进程I D和线程ID。例如,当一个进程被创建时,系统为它指定一个进程对象,并为它赋予ID值1 2 2。如果创建了一个新进程对象,系统不会将相同的I D赋予给它。但是,如果第一个进程对象被释放,系统就可以将1 2 2赋予创建的下一个进程对象。记住这一点后,就能避免编写引用不正确的进程对象或线程对象的代码。获取进程I D是很容易的,保存该I D也不难,但是,接下来你应该知道,该I D标识的进程已被释放,新进程被创建并被赋予相同的I D。当使用已经保存的进程I D时,最终操作的是新进程,而不是原先获得I D的进程。

        有时,运行的应用程序想要确定它的父进程。首先应该知道只有在生成子进程时,才存在进程之间的父子关系。在子进程开始执行代码前, Windows不再考虑存在什么父子关系。较早的Windows 版本没有提供让进程查询其父进程的函数。现在, ToolHelp 函数通过PROCESSENTRY32 结构使得这种查询成为可能。在这个结构中有一个th32ParentProcess I D成员,根据文档的说明,它能返回进程的父进程的I D。

         系统无法记住每个进程的父进程的I D,但是,由于I D是被立即重复使用的,因此,等到获得父进程的I D时,该I D可能标识了系统中一个完全不同的进程。父进程可能已经终止运行。如果应用程序想要与它的“创建者”进行通信,最好不要使用I D。应该定义一个持久性更好的机制,比如内核对象和窗口句柄等。
 

         若要确保进程I D或线程I D不被重复使用,唯一的方法是保证进程或线程的内核对象不会被撤消。如果刚刚创建了一个新进程或线程,只要不关闭这些对象的句柄,就能够保证进程对象不被撤消。一旦应用程序结束使用该I D,那么调用CloseHandle 就可以释放内核对象,要记住,这时使用或依赖进程I D,对来说将不再安全。如果使用的是子进程,将无法保证父进程或父线程的有效性,除非父进程复制了它自己的进程对象或线程对象的句柄,并让子进程继承这些句柄。

转载:http://blog.csdn.net/akof1314/article/details/5471768

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值