Windows Via C/C++ Part Ⅰ Chapter4: 进程—第一个Windows程序(4)

进程的亲缘性

  通常,进程中的线程可以在主机的任何CPU中执行,在有些情况下,你可能想让线程只运行在指定的CPU子集中,这叫做“处理器亲缘性”,我们将在第七章“线程调度、优先级和亲缘性”中讨论这个话题。

进程的错误模式

  每个进程都关联着一组标志位,用来告诉系统进程如何响应严重错误,比如磁盘介质错误、未处理的异常、文件未找到和数据偏差等。进程通过SetErrorMode函数设置该行为:
参数fuErrorMode的取值可以是表4-3中任何标志位的组合.
SetErrorMode参数可取值

  子进程默认继承父进程的错误模式。比如进程A打开了SEM_NOGPFAULTERRORBOX标志并创建了进程B,那么进程B的错误模式中也会有SEM_NOGPFAULTERRORBOX。但子进程B并不知道自己继承了该错误模式标志,它可能没有准备处理GP错误的代码。如果B中的任一线程运行时发生了GP错误,进程B会因此终止而用户得不到任何消息。父进程可以在CreateProcess函数中指定CREATE_DEFAULT_ERROR_MODE标志,以阻止子进程继承其错误模式。

进程的当前驱动器和目录

  当Windows函数需要文件/目录路径为其参数,调用者又没有提供完整路径时,函数会在当前驱动器的当前目录中查找该路径。比如,线程调用CreateFile打开文件且没有指定完整文件路径时,系统会在当前驱动器的当前目录中查找该文件。

  系统在其内部保存进程的当前驱动器和当前目录并跟踪其变化。由于当前驱动器和当前目录是以进程为单位保存的,因此如果进程中的任何线程改变了当前驱动器或目录时,进程中的所有线程都会受到影响。线程可以通过下面的函数获取并设置其当前驱动器/目录:
如果你提供的缓冲区pszCurDir不够大,GetCurrentDirectory会返回存储结果所需的字符数目(包括结束符0),且不对pszCurDir做任何更改。调用成功时,GetCurrentDirectory函数返回获得的字符串长度,不包括结束符0。在WinDef.h中定义的MAX_PATH宏是目录/文件路径的最大长度(260),因此将MAX_PATH作为GetCurrentDirectory的cchCurDir参数总是安全的。

进程的当前目录

  系统会跟踪进程的当前驱动器和目录,但并不会跟踪每个驱动器的当前目录。然而有些操作系统支持对多个驱动器的当前目录的处理,这是通过进程环境变量实现的。比如进程C盘的当前目录是/Utility/Bin,D盘的当前目录是/Program Files,那么其环境块中会包含下面的内容:
=C:=C:/Utility/Bin
=D:=D:/Program Files

  如果你在调用函数时传递的参数中包含驱动器修饰名(如C:、D:),而该驱动器并不是进程的当前驱动器,系统就会在进程环境块中查找和指定的驱动器名关联的变量。如果变量存在,系统使用变量值作为当前目录,如果不存在,系统将使用指定驱动器的根目录做为当前目录。比如进程当前目录是C:/Utility/Bin,当你调用CreateFile打开文件D:ReadMe.txt时,系统会在环境变量中查找变量=D: ,由于=D: 已经存在且其值为D:/Program Files,系统就打开文件D:/Program Files/ReadMe.txt。假如=D:不存在,系统将在D盘根目录下打开文件ReadMe.txt。Windows文件处理函数不会增加或改变驱动器环境变量,它们只是读取其值。

  除了使用SetCurrentDirectory改变进程当前目录,你还可以调用CRT函数_chdir,_chdir在其内部调用了SetCurrentDirectory,同时它也调用SetEnvironmentVariable添加或者修改了进程的驱动器环境变量,这样不同驱动器的当前目录可以被保存下来,而SetCurrentDirectory则仅改变当前驱动器和当前目录,不会对进程环境变量做任何修改。

  假如父进程在创建子进程时指定了子进程的环境变量块(通过CreateProcess的pvEnvironment参数),那么子进程就不会继承父进程自身的环境变量,包括当前目录变量,此时子进程中每个驱动器的当前目录默认为每个驱动器的根目录。此时假如你想让子进程继承父进程的当前目录,父进程必须把这些变量添加到为子进程准备的环境变量块,然后再创建子进程。父进程可以调用函数GetFullPathName获得自己的当前目录:

比如为了获取C驱动器的当前目录,你可以做如下调用:
在取得了这些变量之后,按习惯,你应该将它们放在环境变量块开头。

  下面的代码对本节的概念做了一些说明:

系统版本

  应用程序有时需要Windows系统的版本信息。比如程序可能要用到处理Windows事务文件系统的函数如CreateFileTransacted,但只有Vista及后续版本的操作系统才支持事务文件操作。

  Windows API提供了GetVersion函数:
GetVersion起初是为16位Windows设计的,其返回值的高字表示MS-DOS版本号,低字表示Windows版本号,每个字的高字节表示主版本号,低字节表示次版本号。不幸的是,实现该函数的程序员犯了一个小错误——将Windows版本号的主版本号写在了返回值的低字节,而把次版本号写在了高字节。因为发现该bug时GetVersion已被广泛使用,微软被迫保留了这个小bug并修改了文档以反应这个问题。

  GetVersion的返回值可能会使开发人员混淆,因此微软增加了函数GetVersionEx:
GetVersionEx接收一个指向OSVERSIONINFOEX结构的指针为其参数,OSVERSIONINFOEX结构定义如下:
OSVERSIONINFOEX结构在Windows 2000及后续版本的系统中定义,之前版本的Windows使用较旧的OSVERSIONINFO结构。表4-4是OSVERSIONINFOEX结构各成员的说明:
OSVERSIONINFOEX结构成员说明
在MSDN的"Getting the System Version"(http://msdn2.microsoft.com/en-gb/library/ms724429.aspx)小节,你可以看到使用OSVERSIONINFOEX结构获取系统信息的详细例子。

[原文在此讲述了VerifyVersionInfo的用法,该函数主要用于比较系统信息,类似于GetVersionEx,此处不译,有兴趣的朋友可以自己参阅MSDN]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值