windows 核心编程 笔记之 进程

发表时间:2013.5.18

内容:windows进程(process)

作者:郑金玮

 

如上图所示,windows任务管理器中的进程Tab列中列出了系统管理的所有进程,我们经常利用任务管理器来结束某个没有得到响应的应用程序,但是,作为一个windows程序员,我们应该有这样的疑问:进程是什么东西?系统为什么会存在进程?进程有哪些属性?进程是怎样工作的?以及我们自己写的程序中能不能用进程,且应该怎样使用....?......带着这些问题,我自己参考了微软技术丛书--《windows核心编程》,现在请允许我将自己获取的一些知识总结出来,希望对初学的大家有些许帮助。

 

“进程是一个正在运行的实例”,《核心编程》是这样给进程下定义的

“被加载到内存中执行的程序实例,称为进程(process)”《操作系统》的定义

的确,当我们在windows某个驱动盘符下的文件夹中双击左键执行某个文件程序,然后程序运行,这就是一个实例,我在前面章节中也说过,有些程序只允许一个实例运行,最具代表性的就是网络游戏,当我们运行网络游戏程序(如CF),会顺利执行,弹出一个窗口,再次双击文件,还是只有一个窗口,甚至第二次执行时会弹出一个提示框,类似于:“当前已有...实例在运行”(如:DNF),我想举了这样一些例子,大家应该明白了什么是实例了.

 

进程作为一个正在运行的实例,那么进程内部到底是怎样实现的?

“进程有两个部分组成:

1.一个内核对象,操作系统用这个内核对象来管理进程

2.一个地址空间,其中包含所有可执行文件或DLL模块的代码和数据,此外还包含动态内存分配,比如线程堆栈和堆的分配。”(《windows核心编程》)

 

进程作为应用程序的一部分,操作系统是利用内核对象来管理进程,什么是内核对象?

 

内核对象其实是个小型的数据结构,每当进程创建时由系统分配空间去创建一个内核对象去管理进程,由这个内核对象去统计一些有关进程的一些信息。

我们写windows程序,每当进入winmain函数入口点,由系统分配地址空间,由CS:IP指向程序首地址,有系统创建进程,然后由这个进程去创建线程(有关线程,下面再述),这个进程就称作主进程,其实进程具有“惰性”,就是因为进程要执行一些事务,必须由线程去执行,进程就相当于线程的容器,线程在进程的上下文中运行。

 

所以我们写的程序最起码都包含一个进程和一个线程,虽然我们没有显式地去创建这个进程和线程,这些工作都是有系统去完成的,一般的,如果我们的程序不是很强大,没有必要去创建进程,因为下一章节介绍的线程会让我们的程序更加容易实现(设计到进程间通信相对于线程间通信要复杂),还有,如果我们写GUI程序,一般由一个线程去做这些界面工作,没有必要去创建额外的线程。

 

为什么存在进程?

windows操作系统是基于时间片分配的分时操作系统,对于只有一个处理器的PC来说,系统要执行一堆程序,必须给每个程序分配一个时间片,然后让他们轮循执行,可以这么说,在每个时刻,windows操作系统肯定只有一个程序在执行,而在下一时刻,可能刚才执行的程序已经挂起,而这样一些工作,系统就是利用进程来管理实现的。

每当进程创建,系统会将该进程加入一个队列,这个队列一直在执行,对于队列,我们知道,它是先进先出的一个数据结构。系统创建这个队列来容纳所有创建的进程,然后让他们轮询执行,所以当应用程序过多时,系统的响应就就会越慢,这是显而易见的,因为每个时刻只允许一个进程执行,此时其他进程必须挂起,等待该进程运行的时间片结束,然后轮到下一个要等待执行的进程执行。

 

我们自己的程序如何实现进程,多进程的程序好吗?

虽然我们自己写的最简单的程序拥有一个进程,这个进程有系统创建和分配,但是有时候,我们的程序为了达到高性能的要求,必须创建额外的进程去管理数据,因为对于一个对UI响应要求高的I/O或NET程序来说,I/O的操作绝不可以影响UI的响应,否则会引起死锁,例如当我们玩游戏的时候,有事网络带宽太低,游戏的界面得不到响应,这时候如果按下鼠标左键和键盘上的任意键,一般系统会弹出一个对话框,提示“结束程序”和“取消”,并且界面出现白热化。多进程能改保证I/O操作和UI操作能同步执行,互不影响。还有,例如我们写一个程序,这个程序一直在播放背景音乐,那么我们可以把这个动作放在额外的进程中去,我们熟知的利用GetOpenfilename打开本地文件对话框时,一般会出现短暂性的等待,且用户指针会编程ICON_WAIT所指定的动态圆圈(win7,win vista)(winXP是漏斗),这说明打开这个对话框确实耗费了一定的内存,此时,我们也可以创建额外的进程(或线程)去提高性能。

 

实现进程的方法:

windows platform SDK提供了一些API供程序使用,可以很简单的使用进程。

createprocess(...) 我们利用这个函数可以创建一个进程,此时系统会分配一个内核对象去管理它,这个函数返回的是一个句柄(handle),所谓句柄,实际上是一个标识符,是内存空间的一个基地址,系统会将这个基地址与进程的映像相关联,不用想太多,我们只要知道,这个句柄就是用来标识进程就行了。(我们可以利用getmodulehandle(..)获取一些有用的信息,如果给参数传入.EXE文件的路径或者DLL文件路径的话就会获取该可执行文件的句柄,如果传NULL,就是获取当前程序的主进程句柄(主进程基地址)),一旦我们对这个句柄不感兴趣了(我们以后肯能用不到它了),就要调用closehandle(..)关闭句柄,记住,仅仅是关闭而已,该句柄标记的进程仍然在运行。

 

当我们想退出进程,如何实现?

exitprocess(..)可以显式地结束某个进程

terminateprocess(..)让外部的进程可以结束任何其他进程(任务管理器就是这样实现结束进程的)

虽然有这样一些API,但是windows并不提倡使用他们去结束进程,最好的方法就是我们程序员什么也不做,让进程在主调进程的入口点返回,这样可以保证所有进程都可以顺利结束自己的一生。

 

进程终止时,发生了什么?

1.终止进程中遗留的任何线程

2.释放进程分配所有对象

3.进程的退出代码从STILL_ACTIVE变为进程退出函数的代码

4.进程内核对象的状态变为触发状态

5.进程的内核对象的使用计数减1

 

分析:1,因为进程是线程的容器,进程并不执行任何代码,一旦进程的生命周期结束,它所拥有的所有线程必将结束,很容易理解,因为装线程的容器都没了,线程也就不复存在了

2.进程既然是线程的容器,那么线程中所拥有的任何内核对象必将销毁,包括GDI对象(内核)和用户对象。

5.管理进程的是系统的内核对象,而一个进程可能被多个其他进程使用(打开),而内核对象的使用计数就是标识使用次数的,例如:我们有时遇到这中情况,当我们的U盘插在USB接口上使用,然后退出U盘,可能会出现提示无法正常退出,因为某个U盘内的程序已经打开,没有关闭,但是我们怎么找都找不到到底是哪个文件没有关闭,就是因为内核对象的使用计数没有递减到0,因为每当我们关闭一个文件,管理该文件的内核对象的使用计数会减1,但是处于某种原因,在打开另一个文件的时候,无意中打开了另一个文件的句柄,可能是在内部共享某个DLL,也可能是数据重叠,反正就是把那个文件的句柄打开了,于是内核对象的使用计数就加1,可是系统只知道,要想正常退出,必须保证内核对象的使用计数为零。。。

 

 

再次强调,我们应该尽可能的用线程代替进程,关于线程,请参照下一节:《windows核心编程》之线程、线程同步,线程与进程的关系,线程与作业的关系,进程间通信和线程间通信

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了小程序应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值