进程与线程不平凡的一生

来源:互联网 发布:霍华德场均数据 编辑:程序博客网 时间:2024/06/02 15:53

[进程的生命历程]

执行一个程序,必然就产生一个进程(Process)。最直接的程序执行方式就是在shell(如 Windows 9x的资源管理器或Windows 3.x的文件管理器)中以鼠标双击某一个可执行文件图标(假设其为App.exe),执行起来的App进程其实是shell调用CreateProcess激活的。让我们看看整个流程:

        1shell调用CreateProcess激活App.exe

        2、系统产生一个“进程核心对象”,计数值为1

        3、系统为此进程建立一个 4GB 地址空间。

4、加载器将必要的码加载到上述地址空间中,包括App.exe的程序、数据,以及所需的动态链接函数库(DLLs)。加载器如何知道要加载哪些DLLs呢?它们被记录在可执行文件(PE档案格式)的 .idata section 中。

5、系统为些进程建立一个线程,称为主线程(primary thread)。线程才是CPU时间分配的对象。

6、系统调用C Runtime函数库的Startup code

7Startup code调用App程序的WinMain函数。

8App程序开始运行。

9、用户关闭App主窗口,使WinMain中的消息循环结束掉,于是WinMain结束。

10、回到Startup code

11、回到系统,系统调用ExitProcess结束进程。

可以说,通过这种方式执行起来的所有Windows程序,都是shell的子进程。本来,母进程与子进程之间可能有某些关系存在,但shell在调用CreateProcess时已经把母子之间的脐带关系剪断了,因此它们事实上是独立个体。

 

[线程的生命历程]

 

执行程序代码,是线程的工作。当一个进程建立起来后,主线程也产生。所以每一个Windwos程序一开始就有了一个线程。我们可以调用CreateThread产生额外的线程,系统会帮我们完成下列事情:
  1.配置“线程对象”,其handle将成为CreateThread的返回值。
  2.设定计数值为1。
  3.配置线程的context。
  4.保留线程的堆栈。
  5.将context中的堆栈指针寄存器(SS)和指令指针寄存器(IP)设定妥当。

  当CreateThread成功时,系统为我们把一个线程应该有的东西都准备好。线程的主体在哪里呢?就在所谓的线程处理函数(就相当于窗口的消息处理函数的重要性)。线程与线程之间,不必考虑控制权释放的问题,因为Win32操作系统的特点是强制性多任务的。

  线程的结束有两种情况,一种是寿终正寝,一种是求得善终。前者是线程函数正常结束退出,那么线程也就自然而然终结了。这时候系统会调用ExitThread便有些善后清理工作(其实线程中也可以自行调用此函数以结束自己)。一是进程结束(自然也就导致线程的结束),二是别的线程强制以TerminateThread将它终结掉。不过,TerminateThread太过毒辣,若非必要还是少用为妙(请参考API手册)。

原创粉丝点击