Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1613003
  • 博文数量: 585
  • 博客积分: 14610
  • 博客等级: 上将
  • 技术积分: 7402
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-15 10:52
文章存档

2013年(5)

2012年(214)

2011年(56)

2010年(66)

2009年(44)

2008年(200)

分类: C/C++

2012-01-27 02:15:53

 PROCESS_INFORMATION结构体
分类: 2.1 VC++/MFC 309人阅读 评论(0) 收藏 举报
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://hi.baidu.com/netcicala/blog/item/6bff1c2e646abb554fc226e2.html

阅读(443) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~