系统调用和编程语言的移植性
操作系统控制硬件的功能,都是通过一些小的函数集合体的形式来提供的。这些函数以及调用函数的行为称为系统调用
,也就是通过应用进而调用操作系统的意思。在前面的程序中用到了 time()
以及 printf()
函数,这些函数内部也封装了系统调用。
C 语言等高级编程语言并不依存于特定的操作系统,这是因为人们希望不管是Windows
操作系统还是 Linux
操作系统都能够使用相同的源代码。因此,高级编程语言的机制就是,使用独自的函数名,然后在编译的时候将其转换为系统调用的方式(也有可能是多个系统调用的组合)。也就是说,高级语言编写的应用在编译后,就转换成了利用系统调用的本地代码。
不过,在高级语言中也存在直接调用系统调用的编程语言,不过,利用这种方式做成应用,移植性并不友好。
移植性:移植性指的是同样的程序在不同操作系统下运行时所花费的时间,时间越少证明移植性越好。
操作系统和高级编程语言使硬件抽象化
通过使用操作系统提供的系统调用,程序员不必直接编写控制硬件的程序,而且,通过使用高级编程语言,有时也无需考虑系统调用的存在,系统调用往往是自动触发的,操作系统和高级编程语言能够使硬件抽象化,这很了不起。
下面让我们看一个硬件抽象化的具体实例
#include <stdio.h> void main(){ // 打开文件 FILE *fp = fopen("MyFile.txt","w"); // 写入文件 fputs("你好", fp); // 关闭文件 fclose(fp); }
上述代码使用 C 编写的程序,fputs()
是用来往文件中写入字符串的函数,fclose()
是用来关闭文件的函数。
上述应用在编译运行后,会向文件中写入 "你好" 字符串。文件是操作系统对磁盘空间的抽象化,就如同我们在 程序员需要了解的硬核知识之磁盘 这篇文章提到的一样,磁盘就如同树的年轮,磁盘的读写是以扇区为单位的,通过磁道来寻址,如果直接对硬件读写的话,那么就会变为通过向磁盘用的 I/O 指定扇区位置来对数据进行读写了。
但是,在上面代码中,扇区压根就没有出现过传递给 fopen() 函数的参数,是文件名 MyFile.txt
和指定文件写入的 w
。传递给 fputs() 的参数,是往文件中写入的字符串"你好" 和 fp,传递给 fclose() 的参数,也仅仅是 fp,也就是说磁盘通过打开文件这个操作,把磁盘抽象化了,打开文件这个操作就可以说是操作硬件的指令。
下面让我们来看一下代码清单中 fp 的功能,变量 fp 中被赋予的是 fopen() 函数的返回值,该值被称为文件指针
。应用打开文件后,操作系统就会自动申请分配用来管理文件读写的内存空间。内存地址可以通过 fopen() 函数的返回值获得。用 fopen() 打开文件后,接下来就是通过制定的文件指针进行操作,正因为如此,fputs() 和 fclose() 以及 fclose() 参数中都制定了文件指针。
由此我们可以得出一个结论,应用程序是通过系统调用,磁盘抽象来实现对硬盘的控制的。
Windows 操作系统的特征
Windows 操作系统是世界上用户数量最庞大的群体,作为 Windows 操作系统的资深
用户,你都知道 Windows 操作系统有哪些特征吗?下面列举了一些 Windows 操作系统的特性
- Windows 操作系统有两个版本:32位和64位
- 通过
API
函数集成来提供系统调用 - 提供了采用图形用户界面的用户界面
- 通过
WYSIWYG
实现打印输出,WYSIWYG 其实就是 What You See Is What You Get ,值得是显示器上显示的图形和文本都是可以原样输出到打印机打印的。 - 提供多任务功能,即能够同时开启多个任务
- 提供网络功能和数据库功能
- 通过即插即用实现设备驱动的自设定
这些是对程序员来讲比较有意义的一些特征,下面针对这些特征来进行分别的介绍
32位操作系统
这里表示的32位操作系统表示的是处理效率最高的数据大小。Windows 处理数据的基本单位是 32 位。这与最一开始在 MS-DOS
等16位操作系统不同,因为在16位操作系统中处理32位数据需要两次,而32位操作系统只需要一次就能够处理32位的数据,所以一般在 windows 上的应用,它们的最高能够处理的数据都是 32 位的。
比如,用 C 语言来处理整数数据时,有8位的 char
类型,16位的short
类型,以及32位的long
类型三个选项,使用位数较大的 long 类型进行处理的话,增加的只是内存以及磁盘的开销,对性能影响不大。
现在市面上大部分都是64位操作系统了,64位操作系统也是如此。
通过 API 函数集来提供系统调用
Windows 是通过名为 API
的函数集来提供系统调用的。API是联系应用程序和操作系统之间的接口,全称叫做 Application Programming Interface
,应用程序接口。
当前主流的32位版 Windows API 也称为 Win32 API
,之所以这样命名,是需要和不同的操作系统进行区分,比如最一开始的 16 位版的 Win16 API
,和后来流行的 Win64 API
。
API 通过多个 DLL 文件来提供,各个 API 的实体都是用 C 语言编写的函数。所以,在 C 语言环境下,使用 API 更加容易,比如 API 所用到的 MessageBox()
函数,就被保存在了 Windows 提供的 user32.dll 这个 DLL 文件中。
提供采用了 GUI 的用户界面
GUI(Graphical User Interface)
指得就是图形用户界面,通过点击显示器中的窗口以及图标等可视化的用户界面,举个例子:Linux 操作系统就有两个版本,一种是简洁版,直接通过命令行控制硬件,还有一种是可视化版,通过光标点击图形界面来控制硬件。
通过 WYSIWYG 实现打印输出
WYSIWYG 指的是显示器上输出的内容可以直接通过打印机打印输出。在 Windows 中,显示器和打印机被认作同等的图形输出设备处理的,该功能也为 WYSIWYG 提供了条件。
借助 WYSIWYG 功能,程序员可以轻松不少。最初,为了实现在显示器中显示和在打印机中打印,就必须分别编写各自的程序,而在 Windows 中,可以借助 WYSIWYG 基本上在一个程序中就可以做到显示和打印这两个功能了。
提供多任务功能
多任务指的就是同时能够运行多个应用程序的功能,Windows 是通过时钟分割
技术来实现多任务功能的。时钟分割指的是短时间间隔内,多个程序切换运行的方式。在用户看来,就好像是多个程序在同时运行,其底层是 CPU 时间切片
,这也是多线程多任务的核心。
提供网络功能和数据库功能
Windows 中,网络功能是作为标准功能提供的。数据库(数据库服务器)功能有时也会在后面追加。网络功能和数据库功能虽然并不是操作系统不可或缺的,但因为它们和操作系统很接近,所以被统称为中间件
而不是应用。意思是处于操作系统和应用的中间层,操作系统和中间件组合在一起,称为系统软件
。应用不仅可以利用操作系统,也可以利用中间件的功能。
相对于操作系统一旦安装就不能轻易更换,中间件可以根据需要进行更换,不过,对于大部分应用来说,更换中间件的话,会造成应用也随之更换,从这个角度来说,更换中间件也不是那么容易。
通过即插即用实现设备驱动的自动设定
即插即用(Plug-and-Play)
指的是新的设备连接(plug) 后就可以直接使用的机制,新设备连接计算机后,计算机就会自动安装和设定用来控制该设备的驱动程序
设备驱动是操作系统的一部分,提供了同硬件进行基本的输入输出的功能。键盘、鼠标、显示器、磁盘装置等,这些计算机中必备的硬件的设备驱动,一般都是随操作系统一起安装的。
有时 DLL 文件也会同设备驱动文件一起安装。这些 DLL 文件中存储着用来利用该新追加的硬件API,通过 API ,可以制作出运行该硬件的新应用。