没有合适的资源?快使用搜索试试~ 我知道了~
1111111111111111111111进程.pdf
需积分: 3 1 下载量 93 浏览量
2024-04-01
15:13:03
上传
评论
收藏 2.31MB PDF 举报
温馨提示
试读
46页
资料讲解了进程相关的知识
资源推荐
资源详情
资源评论
下载
第4章 进 程
本章介绍系统如何管理所有正在运行的应用程序。首先讲述什么是进程,以及系统如何创
建进程内核对象,以便管理每个进程。然后将说明如何使用相关的内核对象来对进程进行操作。
接着,要介绍进程的各种不同的属性,以及查询和修改这些属性所用的若干个函数。还要讲述
创建或生成系统中的辅助进程所用的函数。当然,如果不深入说明如何来结束进程的运行,那
么这样的介绍肯定是不完整的。现在就来介绍进程的有关内容。
进程通常被定义为一个正在运行的程序的实例,它由两个部分组成:
• 一个是操作系统用来管理进程的内核对象。内核对象也是系统用来存放关于进程的统计
信息的地方。
• 另一个是地址空间,它包含所有可执行模块或 D L L 模块的代码和数据。它还包含动态内
存分配的空间。如线程堆栈和堆分配空间。
进程是不活泼的。若要使进程完成某项操作,它必须拥有一个在它的环境中运行的线程,
该线程负责执行包含在进程的地址空间中的代码。实际上,单个进程可能包含若干个线程,所
有这些线程都“同时”执行进程地址空间中
的代码。为此,每个线程都有它自己的一组
C P U 寄存器和它自己的堆栈。每个进程至少
拥有一个线程,来执行进程的地址空间中的
代码。如果没有线程来执行进程的地址空间
中的代码,那么进程就没有存在的理由了,
系统就将自动撤消该进程和它的地址空间。
若要使所有这些线程都能运行,操作系
统就要为每个线程安排一定的 C P U 时间。它
通过以一种循环方式为线程提供时间片(称
为量程),造成一种假象,仿佛所有线程都是
同时运行的一样。图4 - 1 显示了在单个C P U的
计算机上是如何实现这种运行方式的。如果
计算机拥有多个 C P U ,那么操作系统就要使
用复杂得多的算法来实现 C P U上线程负载的
平衡。
当创建一个进程时,系统会自动创建它的第一个线程,称为主线程。然后,该线程可以创
建其他的线程,而这些线程又能创建更多的线程。
Wi n d o w s 2 0 0 0 Micorsoft Windows 2000能够在拥有多个C P U的计算机上运行。例如,
我用来撰写本书的计算机就包含两个处理器。 Windows 2000可以在每个C P U 上运行不
第二部分 编程的具体方法
线程
线程
线程
线程
线程
图4-1 操作系统在单个C P U计算机上用循环
方式为各个线程提供时间片
线程
线程
线程
线程
线程
线程
线程
同的线程,这样,多个线程就真的在同时运行了。 Windows 2000的内核能够在这种类
型的系统上进行所有线程的管理和调度。不必在代码中进行任何特定的设置就能利用
多处理器提供的各种优点。
Windows 98 Windows 98只能在单处理器计算机上运行。即使计算机配有多个处理
器,Wi n d o w s每次只能安排一个线程运行,而其他的处理器则处于空闲状态。
4.1 编写第一个Wi n d o w s应用程序
Wi n d o w s支持两种类型的应用程序。一种是基于图形用户界面( G U I)的应用程序,另一
种是基于控制台用户界面(C U I)的应用程序。基于G U I 的应用程序有一个图形前端程序。它能
创建窗口,拥有菜单,可以通过对话框与用户打交道,并可使用所有的标准“ Wi n d o w s”组件。
Wi n d o w s配备的所有应用程序附件(如N o t e p a d、C a l c u l a t o r和Wo r d P a d),几乎都是基于G U I的应
用程序。基于控制台的应用程序属于文本操作的应用程序。它们通常不能用于创建窗口或处理
消息,并且它们不需要图形用户界面。虽然基于 C U I的应用程序包含在屏幕上的窗口中,但是
窗口只包含文本。命令外壳程序 C M D . E X E(用于Windows 2000)和COMMAND.COM (用于
Windows 98)都是典型的基于C U I的应用程序。
这两种类型的应用程序之间的界限是非常模糊的。可以创建用于显示对话框的 C U I 应用程
序。例如,命令外壳程序可能拥有一个特殊的命令,使它能够显示一个图形对话框,在这个对
话框中,可以选定你要执行的命令,而不必记住该外壳程序支持的各个不同的命令。也可以创
建一个基于G U I的应用程序,它能将文本字符串输出到一个控制台窗口。我常常创建用于建立
控制台窗口的G U I应用程序,在这个窗口中,我可以查看应用程序执行时的调试信息。当然你
也可以在应用程序中使用图形用户界面,而不是老式的字符界面,因为字符界面使用起来不太
方便。
当使用Microsoft Visual C++来创建应用程序时,这种集成式环境安装了许多不同的链接程
序开关,这样,链接程序就可以将相应的子系统嵌入产生的可执行程序。用于 C U I应用程序的
链接程序开关是 / S U B S Y S T E M : C O N D O L E,而用于 G U I 应用程序的链接程序开关是
S U B S Y S T E M : W I N D O W S 。当用户运行一个应用程序时,操作系统的加载程序就会查看可执
行图形程序的标题,并抓取该子系统的值。如果该值指明一个 C U I应用程序,那么加载程序就
会自动保证为该应用程序创建文本控制台窗口。
如果该值指明这是个G U I应用程序,那么加载程序不创建控制台窗口,而只是加载应用程
序。一旦应用程序启动运行,操作系统就不再考虑应用程序拥有什么类型的用户界面。
Wi n d o w s应用程序必须拥有一个在应用程序启动运行时调用的进入点函数。可以使用的进
入点函数有4个:
46计计第二部分 编程的具体方法
下载
操作系统实际上并不调用你编写的进入点函数。它调用的是 C / C + + 运行期启动函数。该函
数负责对C / C + +运行期库进行初始化,这样,就可以调用 m a l l o c和f r e e之类的函数。它还能够确
保已经声明的任何全局对象和静态 C + +对象能够在代码执行以前正确地创建。下面说明源代码
中可以实现哪个进入点以及何时使用该进入点(见表4 - 1 )。
表4-1 应用程序的进入点
应用程序类型 进 入 点 嵌入可执行文件的启动函数
需要A N S I 字符和字符串的G U I应用程序 Wi n M a i n Wi n M a i n C RT S t a r t u p
需要U n i c o d e字符和字符串的G U I 应用程序 w Wi n M a i n w Wi n M a i n C RT S t a r t u p
需要A N S I字符和字符串的C U I应用程序 m a i n m a i n C RT S t a r t u p
需要U n i c o d e字符和字符串的C U I应用程序 w m a i n w m a i n C RT S t a r t u p
链接程序负责在它连接可执行文件时选择相应的 C / C + +运行期启动函数。如果设定了
/ S U B S Y S T E M : W I N D O W S链接程序开关,那么该链接程序期望找到一个 Wi n M a i n 或w Wi n m a i n
函数。如果这两个函数都不存在,链接程序便返回一个“未转换的外部符号”的错误消息。否
则,它可以分别选择Wi n M a i n C RT S t a r t u p函数或w Wi n M a i n C RT S t a r t u p 函数。
同样,如果设定了 / S U B S Y S T E M : C O N S O L E 链接程序开关,那么该链接程序便期望找到
m a i n或w m a i n函数,并且可以分别选择 m a i n C RT S t a r t u p 函数或w m a i n C RT S t a r t u p 函数。同样,
如果m a i n或w m a i n都不存在,那么链接程序返回一条“未转换外部符号”的消息。
但是,人们很少知道这样一个情况,即可以从应用程序中全部删除 / S U B S Y S T E M 链接程
序开关。当这样做的时候,链接程序能够自动确定应用程序应该连接到哪个子系统。当进行链
接时,链接程序要查看代码中存在 4个函数(Wi n M a i n、w Wi n M a i n 、m a i n 或w m a i n )中的哪一
个。然后确定可执行程序应该是哪一个子系统,并且确定可执行程序中应该嵌入哪个 C / C + + 启
动函数。
Wi n d o w s / Visual C++编程新手常犯的错误之一是,当创建新的应用程序时,不小心选择了
错误的应用程序类型。例如,编程员可能创建一个新的 Wi n 3 2应用程序项目,但是创建了一个
进入点函数m a i n 。当创建应用程序时,编程员会看到一个链接程序错误消息,因为 w i n 3 2应用
程序项目设置了/ S U B S Y S T E M : W I N D O W S链接程序开关,但是不存在Wi n M a i n或w Wi n M a i n 函
数。这时,编程员可以有4个选择:
• 将m a i n函数改为Wi n M a i n 。通常这不是最佳的选择,因为编程员可能想要创建一个控制
台应用程序。
• 用Visual C++创建一个新的Win32 控制台应用程序,并将现有的源代码添加给新应用程
第 4章 进 程计计47
下载
序项目。这个选项冗长而乏味,因为它好像是从头开始创建应用程序,而且必须删除原
始的应用程序文件。
• 单击 Project Settings对话框的 L i n k 选项卡,将 / S U B S Y S T E M : W I N D O W S开关改为
/ S U B S Y S T E M : C O N S O L E 。这是解决问题的一种比较容易的方法,很少有人知道他们只
需要进行这项操作就行了。
• 单击Project Settings对话框的L i n k选项卡,然后全部删除/ S U B S Y S T E M : W I N D O W S开关。
这是我喜欢选择的方法,因为它提供了最大的灵活性。现在,连接程序将根据源代码中
实现的函数进行正确的操作。当用Visual C++的Developer Studio创建新Wi n 3 2应用程序或
Wi n 3 2控制台应用程序项目时,我不知道为什么这没有成为默认设置。
所有的C / C + + 运行期启动函数的作用基本上都是相同的。它们的差别在于,它们究竟是处
理A N S I 字符串还是U n i c o d e 字符串,以及它们在对 C运行期库进行初始化后它们调用哪个进入
点函数。Visual C++配有C运行期库的源代码。可以在CR t0.c文件中找到这4个启动函数的代码。
现在将启动函数的功能归纳如下:
• 检索指向新进程的完整命令行的指针。
• 检索指向新进程的环境变量的指针。
• 对C / C + + 运行期的全局变量进行初始化。如果包含了 S t d L i b . h 文件,代码就能访问这些变
量。表4 - 1列出了这些变量。
• 对C运行期内存单元分配函数(m a l l o c和c a l l o c)和其他低层输入/输出例程使用的内存栈
进行初始化。
• 为所有全局和静态C + +类对象调用构造函数。
当所有这些初始化操作完成后, C / C + + 启动函数就调用应用程序的进入点函数。如果编写
了一个w Wi n M a i n函数,它将以下面的形式被调用:
如果编写了一个Wi n M a i n函数,它将以下面的形式被调用:
如果编写了一个w m a i n函数,它将以下面的形式被调用:
如果编写了一个m a i n函数,它将以下面的形式被调用:
当进入点函数返回时,启动函数便调用 C运行期的e x i t函数,将返回值(n M a i n R e t Va l)传
递给它。E x i t函数负责下面的操作:
• 调用由_ o n e x i t函数的调用而注册的任何函数。
• 为所有全局的和静态的C + +类对象调用析构函数。
• 调用操作系统的E x i t P r o c e s s函数,将n M a i n R e t Va l传递给它。这使得该操作系统能够撤消
进程并设置它的e x i t代码。
48计计第二部分 编程的具体方法
下载
表4 - 2 显示了程序能够使用的C / C + +运行期全局变量。
表4-2 程序能够使用的C / C + +运行期全局变量
变 量 名 类 型 说 明
_ o s v e r unsigned int 操作系统的测试版本。例如,Windows 2000 Beta 3是测
试版本2 0 3 1 。因此_ o s v e r的值是2 0 3 1
_ w i n m a j o r unsigned int 采用十六进制表示法的Wi n d o w s主要版本。对于Wi n d o w s
2 0 0 0来说,它的值是5
_ w i n m i n o r unsigned int 采用十六进制表示法的Wi n d o w s次要版本。对于Wi n d o w s
2 0 0 0 来说,它的值是0
_ w i n v e r unsigned int ( _ w i n m a j o r < < 8 ) + _ w i n m i n o r在命令行上传递的参数号
- - a rg c unsigned int
- - a rg v c h a r * * 带有指向A N S I / U n i c o d e字符串的指针的_ _ a rg c大小的数组
- - w a rg v w c h a r _ t * * 每个数组项均指向一个命令行参数
_ e n v i r o n c h a r * * 指向A N S I / U n i c o d e字符串的指针的数组。每个数组项指向
_ w e n v i r o n w c h a r _ t * * 一个环境字符串
_ p g m p t r c h a r * 正在运行的程序的A N S I / U n i c o d e全路径和名字
_ w p g m p t r w c h a r _ t *
4.1.1 进程的实例句柄
加载到进程地址空间的每个可执行文件或 D L L 文件均被赋予一个独一无二的实例句柄。可
执行文件的实例作为( w ) Wi n M a i n的第一个参数h i n s t E x e 来传递。对于加载资源的函数调用来说,
通常都需要该句柄的值。例如,若要从可执行文件的映象来加载图标资源,需要调用下面这个
函数:
L o a d I c o n的第一个参数用于指明哪个文件(可执行文件或D L L文件)包含你想加载的资源。
许多应用程序在全局变量中保存 ( w ) Wi n M a i n 的h i n s t E x e 参数,这样,它就很容易被所有可执行
文件的代码访问。
Platform SDK文档中说,有些函数需要H M O D U L E类型的一个参数。它的例子是下面所示
的G e t M o d u l e F i l e N a m e函数:
注意 实际情况说明,H M O D U L E 与H I N S TA N C E是完全相同的对象。如果函数的文
档指明需要一个H M O D U L E ,那么可以传递一个H I N S TA N C E ,反过来,如果需要一
个H I N S TA N C E,也可以传递一个H M O D U L E。之所以存在两个数据类型,原因是在
1 6位Wi n d o w s中,H M O D U L E和H I N S TA N C E 用于标识不同的东西。
( w ) Wi n M a i n的h i n s t E x e参数的实际值是系统将可执行文件的映象加载到进程的地址空间时
使用的基本地址空间。例如,如果系统打开了可执行文件并且将它的内容加载到地址
0 x 0 0 4 0 0 0 0 0中,那么( w ) Wi n M a i n的h i n s t E x e参数的值就是0 x 0 0 4 0 0 0 0 0。
可执行文件的映像加载到的基地址是由链接程序决定的。不同的链接程序可以使用不同的
第 4章 进 程计计49
下载
剩余45页未读,继续阅读
资源评论
qq_23115701
- 粉丝: 0
- 资源: 6
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功