windows 映射文件会释放内存吗_Windows核心编程-进程

本质:一个正在运行的程序的一个实例,由一个内核对象和一个地址空间构成。进程内核对象保存了进程的统计信息,操作系统用它来管理进程。地址空间包含了所有可执行文件或DLL模块的代码和数据,还包含动态内存分配,如线程堆栈和堆的分配。进程和线程紧密关联,进程要做任何事,都必须让一个线程在它的上下文中执行。进程中第一个创建的线程称为主线程。

Windows应用程序:Windows支持两种类型的应用程序:GUI程序(图形用户界面)和CUI(控制台用户界面)程序。GUI是基于图形化的前端,而CUI是基于文本的。Windows应用程序必须有一个入口点函数,应用程序开始运行时被调用。C/C++应用程序的入口点函数如下表:

e7b4a21e30c3f916b6f49149df5b3ad7.png

事实上操作系统并不调用我们所写的入口点函数,而是调用C/C++运行库实现并在链接时使用-entry命令行选项来设置的一个C/C++运行时启动函数。启动函数的作用如下:1)获取指向新进程的完整命令行的一个指针;2)获取指向新进程的环境变量的一个指针;3)初始化C/C++运行库的全局变量;4)初始化C运行库内存分配函数(malloc和calloc)和其他底层I/O例程所使用的的堆。5)调用所有全局和静态C++类对象的构造函数。6)调用应用程序的入口函数。应用程序入口函数返回后,运行库启动函数将调用C运行库函数exit,该函数主要执行以下任务:1)调用)_onexit函数调用所注册的任何一个函数;2)调用全局和静态C++类对象的析构函数;3)在DEBUG中,如果设置了CRTDBG_LEAK_CHECK_DF标志,就通过_CrtDumpMemoryLeaks函数来生成内存泄漏报告。4)调用操作系统的ExitProcess函数,导致操作系统杀死进程。

进程实例句柄:加载到进程地址空间的每一个可执行文件或者DLL文件都被赋予一个独一无二的实例句柄。可执行文件的实例被当做WinMain函数的第一个参数(hInstanceExe)传入,在需要加载资源的函数调用中,需要提供此句柄值。hInstanceExecan参数实际值是一个内存的基地址:操作系统将可执行文件的映像加载到进程地址空间的这个位置。

进程的命令行和环境变量:系统在创建一个新的进程时,会传一个命令行给他。可以通过GetCommandLine函数获取一个指向进程的完整命令行的指针。每个进程都有一个与他关联的环境块,这是在进程地址空间分配的内存块。可以通过GetEnvironmentString函数返回内存块。子进程可以继承父进程的环境变量,但父进程也可以控制哪些环境变量可以被继承(此处的继承是一个副本)。

创建进程:CreateProcess函数用来创建一个进程。创建进程内核对象->创建虚拟地址空间->加载可执行文件(必要的DLL)的代码和数据到进程地址空间->创建主线程的内核对象->主线程执行C/C++运行时启动例程->调用应用程序入口函数。注意在进程完全初始化之前该函数就返回True。

8fcba9abb8199dcd0d01ee8a52710264.png

终止进程:终止Windows进程有以下四种方式:1)主线程的入口点函数返回(最安全的方式);2)进程中的一个线程调用了ExitProcess函数(慎用);3)另外一个进程中的线程调用TerminatepProcess函数(慎用);4)进程中的所有线程自然死亡(几乎不会发生)。

第一种方式可以 保证主线程的所有资源都被正确清理,该线程的任何C++对象都将由其析构函数正确的销毁,操作系统正确释放线程栈使用的内存,系统将进程的退出代码(进程内核对象所维护)设为入口点函数的返回值,系统递减进程内核对象的使用计数。

ExitProcess函数调用将终止进程且该函数不会返回,其后的代码将不会执行。正常情况下,主线程的入口点函数返回时,会回到C/C++运行库启动代码,后者将正确清理运行库的资源,之后C运行库将显示调用ExitProcess来终止进程。当应用程序显示调用ExitProcess函数时,进程当场终止,C/C++运行库将没有机会执行清理工作。

任何线程可以调用TerminatepProcess函数来终止另外一个线程或自己所属的线程。被终止的进程往往来不及执行自己的清理工作,也无法将它在内存中的任何信息flush到磁盘。TerminatepProcess函数是异步的,这表示当函数返回时,不能保证进程已经被强行终止了,但可以通过WaitForSingleObject之类的函数来获得进程的状态。

当进程终止时,操作系统将以此执行一下操作:1)终止进程中遗留的所有线程;2)释放进程分配的所有用户GDI对象,关闭所有的内核对象(内核对象的引用计数为0);3)进程退出代码由STILL_ACTIVE变为传给ExitProcess或TerminatepProcess的代码;4)进程内核对象的状态变为触发状态。进程内核对象的使用计数减1。

子进程:当需要让另外一个进程操作本进程的地址空间中的数据,并且只允许它访问父进程地址口昂见中与它相关的数据,可以用子进程来处理。Windows下,可以通过动态数据交换(DDE)/OLE/管道/邮件槽/内存映射文件等来传递数据。想要独立的运行子进程可以在父进程中对子进程内核对象句柄和子进程的主线程内核对象句柄调用CloseHandle。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值