进程
进程是一个程序的实例,是静态的;
进程不会运行,是线程的容器;
组成部分:
>
一个核心的对象,操作系统用来保存进程的信息;
>
地址空间,包含可执行文件和所有动态链接库的代码和数据,以及动态分配的内存;
进程的终止
进程终止后
,Windows
会释放进程所使用的内存、句柄等所有资源;
进程终止的方式:
>
主线程的入口函数返回(推荐方式)
>
进程主动退出;一个线程调用
ExitProcess
;
>
进程被动终止;另一个进程调用了
TerminateProcess;
>
进程中的所有线程都终止;
从“应用程序”页离选择“结束任务“。
Windows
尝试通知应用程序退出,用户有可能取消。若结束任务失败,而且用户选择终止,
Windows
强行终止应用程序。
从“进程”页里选择“结束进程”。
Windows
强行终止进程,进程中的所有线程被终止,不通知
DLL
,还未完成的
I/O
操作被取消,直到所有
I/O
操作完成或被取消,该进程终止。
线程
>
创建于一个进程的上下文中,在进程的地址空间中运行;
>
线程是动态的,一个进程至少要有一个线程;
>
进程中的所有线程共享进程的地址空间;
组成部分:
>
一个核心态的对象,操作系统用来保存线程的信息;
>
线程堆栈,用于存放线程运行时的函数参数和局部变量等
线程的运行
>
当一个进程初始化时,系统回创建这个进程的主线程;
>
这个线程最初执行
C/C++
运行时间库的启动代码,这些启动代码回调用程序的入口函数(
main,wmain,WinMain,wWinMain
)
;
>GUI
进程有一个主
UI
线程,处理消息循环或用户交互。若这个线程被挂起或忙于处理任务,应用程序回失去响应;
>
工作线程没有界面,在后台工作,例如分析数据、数据库操作等
线程的终止
>
线程函数返回(推荐方式)
>
线程调用
ExitThread;
>
其他线程(可以是其它进程中的线程)调用
TerminateThread
;
>
该线程所在的进程终止
进程的虚拟空间
>
在32位的系统上,进程的虚拟地址空间是4
G
;
>
缺省情况下,用户态和核心态虚拟地址空间各占2
GB;
>
各个进程的用户态地址空间是相互独立的;
用户态虚拟地址空间的状态:
>free
:这段地址自由,可以被分配;
>reserving:
这段地址可以被预留,不会再分配作他用,没有影响影射到物理内存,不能访问,只有被
commit
之后才可以使用;
>committed
:被影射到物理内存;
进程使用的内存
>Private Bytes:
进程的虚拟地址空间中已分配的内存,不包括和其他进程共享的内存;
>Virtual Bytes:
进程所使用的虚拟地址空间的大小,包括和其他进程共享的内存,例如共享的动态链接库。
>Working Set:
进程所使用的物理内存的大小;
内存映射文件
>
进程保留一段虚拟地址空间,把一个文件中的一部分映射到这段地址空间;
>
操作系统使用内存映射文件来装载
.exe
和
.dll
文件。若多个进程使用同一个
dll
文件若多个进程使用同一个
dll
文件,物理内存里只有一份拷贝;
>
使用内存映射文件来处理大文件,每次只把一部分文件内容映射到进程的地址空间;
>
多个进程之间共享内存;多个进程映射到同一个文件的同一部分;
物理内存和
Paging File
>paging file
用来保存进程正在使用的修改过的内存,例如当系统物理内存不足时或这部分内存在很长一段时间内没有使用;
>
当这部分内容被访问时,这些内容再被从
paging file
转移到物理内存;
缺页处理
>
被访问的页面不在物理内存里,但是在硬盘文件里或
paging file
或内存映射文件里;
>
操作系统分配物理内存,把所需要的访问的内容从硬盘文件或
paging file
里读到物理内存里;
>
这个过程对应用程序是透明;
线程堆栈(
stack
)
>
堆栈是线程运行时用来保存参数,局部变量,函数返回地址等数据的一块内存;
>
系统给每个线程
reserve
一块用户态线程堆栈,并
commit
其中的一部分内存。缺省情况下,
reserve !MB
堆栈,并
commit
其中的
2
个
page;
堆
>
分配小块的内存;
>
进程的缺省堆,缺省为
1MB;
进程使用内存的类型总结
>
虚拟内存:用于存储大块的数组或数据结构;
>
内存映射文件:用于映射可执行文件,大文件,或多进程之间共享内存;
>
堆:主要用于大量的小快的内存,进程申请内存一般是从堆栈中分配,进程使用的内存大部分来自堆。堆实际上是操作系统的堆管理器是从虚拟内存分配的;
>
堆栈
:
堆栈保存线程运行时的一些变量,寄存器信息等,堆栈的空间有限,如果一个线程的堆栈用完而且不能再增长,应用程序回崩溃。
动态链接库
>DLL
里的内容:函数,数据结构,资源等;
>DLL
不能直接运行,必须被装载到一个进程中才能运行;
>DLL
的
image
被映射到进程的地址空间,然后进程中的所有线程可以调用
DLL
中的函数。
异常处理
>
应用程序运行时可能遇到异常,如果应用程序没有处理这些异常,应用程序就会崩溃;
常见异常:
>
访问非法内存地址;
>
线程堆栈益处;
>
遇到断点(程序里写有断点);
>
执行非法指令(线程堆栈被破坏)
转载请注明原文地址: https://ibbs.8miu.com/read-50313.html