在计算机中尚不存在操作系统的年代,完全没有任何程序,程序员需要编写出处理相关的所有程序。用机器语言编写程序,然后再使用开关将程序输入,这一过程非常麻烦。于是,有人开发出了仅具有加载和运行功能的监控程序,这就是操作系统的原型。通过事先启动监控程序,程序员根据需要将各种程序加载到内存中运行。
操作系统的原型:监控程序随着时代的发展,人们在利用监控程序编写程序的过程中,发现很多程序都有共通的部分。例如通过键盘输入文字数据、往显示器输出文字数据等。而如果每编写一个新的程序都要记述相同的处理的话,那真的是太浪费时间了。因此,基本入输出部分的程序就被追加到了监控程序中。
操作系统原型2:监控程序+基本的输入输出随着时代的进一步发展,开始有更多的功能被追加到监控程序中,比如,为了方便程序员控制硬件的程序、编程语言处理器(汇编、编译、解析)以及各种实用程序等,结果就形成了和现在相差不大的操作系统。因此,操作系统本身并不是单独的程序,而是多个程序的集合体。
操作系统:程序的集合体由于操作系统诞生后,就没有必要再编写直接控制硬件的程序,程序员主要是利用操作系统功能来开发应用程序,此外掌握硬件的基本知识是必需的,可以借助操作系统进行抽象化,可以大大提高编程效率。
在操作系统运行环境下,应用并不是直接控制硬件,而是通过操作系统来间接控制硬件的。变量定义中涉及的内存的申请分配,以及time()和printf()函数的运行结果,都不是面向硬件而是面向操作系统的。操作系统收到应用发出的指令后,首先会对该指令进行解释,然后会对时钟IC(实时时钟)和显示器用的I/O进行控制。
程序通过OS间接控制硬件操作系统的硬件控制功能,通常是通过一些小的函数集合体的形式来提供的。这些函数及调用函数的行为统称为系统调用(system call)。
C语言等高级编程语言并不依存于特定的操作系统。这是因为人们希望不管是Windows还是Linux,都能使用几乎相同的源代码。因此,高级编程语言的机制是,使用各自开发语言中独自的函数名,然后在编译时将其转换成相应操作系统的系统调用(也有可能是多个系统调用的组合)。也就是说,用高级编程语言编写的应用在编译后,就转换成了利用系统调用的本地代码。
高级编程语言的编译在高级编程语言中,也存在可以直接调用系统调用的编程语言。不过这种方式做成的应用,移植性并不友好(也俗称为有恶意行为的应用)。例如直接调用Windows系统调用的应用,在Linux上显然是无法运行的。
通过使用操作系统提供的系统调用,程序员就没必要编写直接控制硬件的程序了。这是因为操作系统和高级编程语言能够使硬件抽象化。
用C语言编写的往文件中写入字符串的应用。fopen()是用来打开文件的函数,fputs()是用来往文件中写入字符串的函数,fclose()是用来关闭文件的函数。
#include <stdio.h>
void main() {
//打开文件
FILE *fp =fopen("MyFile.txt", "w");
//写入文件
fputs("你好", fp);
//关闭文件
fclose(fp);
}
该应用在编译运行后,MyFile.txt文件中会被写入“你好”字符串。文件是操作系统对磁盘媒介空间的抽象化。作为硬件的磁盘媒介,就如同树木的年轮一样,被划分为了多个扇区,并以扇区为单位对磁盘进行读写。如果直接对硬件进行操作的话,就变成通过向磁盘的I/O指定扇区位置来对数据进行读写。
磁盘媒介的读写采用了文件这个概念,将整个流程抽象化成了打开文件用的fopen()、写入文件用的fputs()、关闭文件用的fclose()。
变量fp中被赋予的是fopen()函数的返回值。该值称为文件指针。应用打开文件后,操作系统就会自动申请分配用来管理文件读写的内存空间。这个内存空间的地址可以通过fopen()函数的返回值获得。用fopen()打开文件后,通过指定文件指针来对文件进行操作。正因为如此,fputs()及fclose()的参数中都指定了文件指针(变量fp)。
就以常用的Windows操作系统为例,来详细讲解操作系统的具体功能。Windows操作系统的主要特征如下所示:
1)32位操作系统(也有64位版本)
这里的32位的是处理效率最高的数据大小。Windows处理数据的基本单位是32位。
2)通过API函数集来提供系统调用
API是联系应用程序和操作系统之间的接口称为API(Application Programming Interface,应用程序接口)。API通过多个DLL文件来提供,各API的实体都是用C语言编写的函数。
3)提供了图形用户界面的用户界面
在像MS-DOS这种没有使用GUI的操作系统中,应用的处理流程由程序员决定,用户按照定好的流程来进行操作即可。与此相反,采用GUI的操作系统中运行的应用,则是由用户决定处理流程的。因此,程序员必须要制作出在任何操作顺序下都能运行的应用。
4)通过WYSIWYG实现打印输出
WYSIWYG指的是显示器上显示的内容可以直接通过打印机打印输出。为了实现在显示器中显示和在打印机中打印,就必须分别编写各自的程序。而在Windows中,借助 WYSIWYG功能,基本上在同一个程序中就可以实现显示和打印这两方面的操作了。
5)提供多任务功能
多任务指的是同时运行多个程序的功能。Windows是通过时钟分割技术来实现多任务功能的。时钟分割指的是在短时间间隔内,多个程序切换运行的方式。此外,Windows中还具有以程序中的函数为单位来进行时钟分割的多线程功能。
6)提供网络功能及数据库功能
Windows中,网络功能是作为标准功能提供的。数据库(数据库服务器)功能有时也会在之后进行追加。网络功能和数据库功能,虽并不是操作系统本身不可欠缺的功能,但因为它们和操作系统很接近,所以被统称为中间件而不是应用。
7)通过即插即用实现设备驱动的自动设定。
即插即用(Plug-and-Play)指的是新的设备连接(Plug)后立刻就可以使用(Play)的机制。新的设备连接到计算机后,系统就会自动安装和设定用来控制该设备的设备驱动程序。
设备驱动是操作系统的一部分,提供了同硬件进行基本的输入输出的功能。键盘、鼠标、显示器、磁盘装置等,这些计算机中必备的硬件的设备驱动,一般都是随操作系统一起安装的。如果之后再追加新的网卡(NIC)等硬件的话,就需要向操作系统追加该硬件专用的设备驱动。大家购买的新的硬件设备中,通常都会附带着软盘或CD-ROM,里面通常都收录着该硬件的设备驱动。
有时DLL文件也会同设备驱动文件一起安装。这些DLL文件中存储着用来利用该新追加硬件的API(函数集)。通过API,可以制作出运用该新硬件的应用。
读书笔记内容整理,来自《程序是怎样跑起来的》
写在最后:
哪些特征的程序适合放在操作系统中?能实现某个通用功能的比如修复文件的xfs_repair和时间同步NTP。
应用打开文件后,操作系统会自动申请分配用来管理文件读写的内存空间。这个内存空间的地址可以通过fopen()函数的返回值获得。---操作系统根据程序的需要进行分配内存,这下可以写个程序来把内存冲爆。
文件是操作系统对磁盘媒介空间的抽象化。通过向文件写数据变成向磁盘的I/O指定扇区位置来对数据进行读写。--想知道某个主机的磁盘IO,去写个文件试试就知道了。
网友评论