进程PID、线程ID、实例Instance、句柄Handle的关系及App.hInstance 的用途

Q:《深入简出MFC》p91下面有这么一句话   
InitApplication和InitInstance现在成为MFC的CWinApp的两个虚函数,前者负责   
“每一个程序只做一次”的操作,后者负责“每一个例程都得做一次”的操作  

 

A:“每一个程序”指的是进程的概念。

“每一个例程”指的是线程的概念。   
 所以InitApplication负责“每一个程序只做一次”的操作。   
 而InitInstance是每一个线程都具有的函数,只不过很多情况下,你自己开的线程没有重载该函数。

 

 

Q:请帮忙说明一下进程PID、线程ID、实例Instance、句柄Handle的关系及App.hInstance 的用途  
  
A:每个PE程序当被执行时,操作系统将为它分配一块内存,并将这个PE程序以及和它相关的动库链接库,一起压栈,压栈成功,则生成一个进程,并且为这个进程分配一个唯一的ID号,我们称这个是PID,就像门牌号码一样,你要找一个已经成功入住的房子,那么你可以靠这个门牌号码找到,当PE程序内部生成新的线程时,那么在这个进程会向操作系统发出申请,此时操作系统会为它分配此内存块中的另一块内存,此时的线程块只是在主进程中另外分配出来的一块,并没有向操作系统申请进程外的内存块,当房子造好后,这个房子里面可以有很多空的房间,那么一开始房间是空在那里的,仅当有人入住时,这个房间才会被开出来,道理是一样的,PE中的代码再有多的线程代码,仅当线程代码被执行时,进程才会向操作系统提出申请,否则此线程将不被执行,这个线程ID就是房间的间号.如果要问PID和线ID之间 的联系的话,那么可以一句话概括即:同一个进程中可以有N个线程,当进程生命周期结束时,它里面不管有多少线程正在工作,都将被停止并回收资源.
Handle是个句柄,每个被成功生成的元都将会生成一个唯一的句柄(当然了有些特殊封装技术生成的的元是没有句柄的,这个我们这里不讨论),通过这个句柄我们可以准确的找到这个元,进行操作
App.hInstance返回操作系统为此PE程序,分配的内存首地址,刚才已经说过了,当PE要正常执行时,必须要被压入内存,既然在内存中存在了,那么它肯定有首地址和尾地址,通过这二个地址组成一个内存块.
  
不管是进程还是线程,理论上面它们是各自独立的,但并不是说不能被注入,有的进程为什么不能被注入,是因为此PE代码在系统底层对此内存块进行了保护,使得我们在外表看出来好像不能被注入,线程也一样,没有不能被注入的内存块,只是写代码的人技术有高低.

 

在WinDef.h有这么一句:typedef HANDLE HINSTANCE;
数据上两者是一样的,本质上没什么区别。

HANDLE是用来标记资源的,也就是handle to an object。
HINSTANCE是Handle to an instance, 是HANDLE的一种特殊情况,常用来标记App实例。

 

 

Q:HINSTANCE指的是一个线程还是一个进程?

 

A:是“模块”的实例,和线程和进程关系不大。

你的应用程序a.exe,可能需要b.dll的支持,那么在程序运行的时候,a.exe这个进程里面就包含了a.exe模块和b.dll模块,而他们的HINSTANCE其实就是每个模块的进程首地址,也叫做基地址。

 

 

Q:winapi编程中instance是个什么东西?

 

A:应用程序实例,
简单的来说,就是用来标识你的应用程序的,windows是多任务操作系统,同时有很多应用程序在运行,需要标识出每个应用程序。
同样,每个应用程序又会有多个窗口,那么每个窗口都有窗口句柄来标识是哪个窗口。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章