程序的生和死

来源:互联网 发布:深圳市康宁医院 知乎 编辑:程序博客网 时间:2024/04/24 02:14

今天给新来的同事讲MFC的消息循环,诸如什么时候启动的,如何循环的,消息是如何传递的等等,结果收效甚微,原因是他们连基本的程序产生到程序运行结束的基本过程都不清楚,所以我决定先梳理一个程序从生到死经历的过程,再讲消息传递。

 

调用CreateProcess创建一个进程内核对象

 

                       ↓

 

系统为进程创建一个私有地址空间(虚拟地址空间)

 

                       ↓

在进程地址空间保留区域将exe文件和需要的DLL映射到进程的地址空间

 

                       ↓

 

找到启动地址(启动函数),开始执行exe文件的启动代码

 

                       ↓

创建主线程

                       ↓

 

调用C/C++运行期启动函数(_tmainCRTStartup,启动函数的功能在本文后面描述) 

 

现在将启动函数的功能归纳如下:

1, 检索指向新进程的完整命令行的指针。

2,检索指向新进程的环境变量的指针。

3,对C / C + +运行期的全局变量进行初始化。如果包含了S t d L i b . h 文件,代码就能访问这些变量。表4 - 1 列出了这些变量。

4,对C 运行期内存单元分配函数(m a l l o c 和c a l l o c )和其他低层输入/输出例程使用的内存栈进行初始化。

5,为所有全局和静态C + +类对象调用构造函数。


 

                   ↓

 

 

启动函数的初始化操作完成后,C / C + +启动函数就调用应用程序的进入点函数(wWinMain)

 

                       ↓

        调用AfxWinMain

 

                       ↓

AfxWinMain中初始化MFC(AfxWinInit)

 

                       ↓

做应用程序初始化,包括创建主窗口(调用主线程的InitInstance)

 

                       ↓

创建成功,进入消息循环(调用主线程的Run)

 

                       ↓

Run从消息队列中取得消息,转换消息,派发消息到各个窗口。

 

                       ↓

当进入点函数返回时,启动函数便调用C 运行期的e x i t 函数,将返回值(n M a i n R e t Va l )传递给它。

E x i t 函数负责下面的操作:

 

1, 调用由_onexit函数的调用而注册的任何函数。

2,为所有全局的和静态的C++类对象调用析构函数。

3,调用操作系统的ExitProcess函数,将nMainRetVal传递给它。这使得该操作系统能够撤消进程并设置它的e x i t 代码。

 

 

 

 

 

                       ↓

 

线程结束

 

 

                       ↓

 

                进程结束

 

 

 

 

 

 


 

原创粉丝点击