为了从操作系统中获得服务,用户程序必须使用系统调用( System Call),系统调用陷入内核并调用操作系统。访管指令把目态切换成管态,并启用操作系统。当有关工作完成之后,在系统调用后面的指令把控制权返回给用户程序。本节介绍系统调用的概念,系统调用的分类,以及系统调用的执行过程。
所谓系统调用,就是用户在程序中调用操作系统所提供的一些子功能。这是一种特殊的过程调用,这种调用通常是由特殊的机器指令实现的。除了提供对操作系统子程序的调用外,这条指令还将系统转入特权方式(管态)。因此,系统调用程序被看成是一个低级的过程,只能由汇编语言直接访问。系统调用是操作系统提供给编程人员的唯一接口。编程人员利用系统调用,动态请求和释放系统资源,调用系统中已有的系统功能来完成与计算机硬件部分相关的工作以及控制程序的执行速度等。因此,系统调用像一个黑箱子那样,对用户屏蔽了操作系统的具体动作而只提供有关的功能。
系统调用与函数调用的区别
由于操作系统的特殊性,应用程序不能采用一般的函数调用方式来调用这些功能过程,而是利用一种系统调用命令去调用所需的操作系统过程。因此,系统调用在本质上是应用程序请求操作系统核心完成某一特定功能的一种函数调用,是一种特殊的函数调用,它与一般的函数调用有以下几方面的区别。
运行在不同的系统状态
一般的函数调用,其调用程序和被调用程序都运行在相同的状态:管态或目态;而系统调用与函数调用的最大区别就在于:调用程序运行在目态,而被调用程序则运行在系统态。
状态的转换
一般的函数调用不涉及系统状态的转换,可直接由调用过程转向被调用过程;但在运行系统调用时,由于调用和被调用过程工作在不同的系统状态,因而不允许由调用过程直接转向被调用过程,通常都是通过软中断机制先由目态转换为管态,在操作系统核心分析之后,转向相应的系统调用处理子程序。
返回问题
般的函数调用在被调用过程执行完后,将返回到调用过程继续执行。但是,在采用抢占式调度方式的系统中,被调用过程执行完后,系统将对所有要求运行的进程进行优先级分析。如果调用进程仍然具有最高优先级,则返回到调用进程继续执行;否则,将引起重新调度,以便让优先级最高的进程优先执行。此时,系统将把调用进程放入就绪队列。
嵌套调用
像一般过程一样,系统调用也允许嵌套调用,即在一个被调用过程的执行期间,还可再利用系统调用命令去调用另一个系统调用。在一般情况下,每个系统对嵌套调用的深度都有定的限制。
系统调用的分类
通常,一个操作系统的功能分为两大部分:一部分是系统自身所需要的;另一部分功能是作为服务提供给用户的,有关这部分功能可以从操作系统所提供的系统调用上体现出来。不同的操作系统所提供的系统调用会有一定的差异。对于一般通用的操作系统而言,可将其所提供的系统调用分为以下几方面。
进程控制类系统调用
这类系统调用主要用于对进程的控制,如创建和终止进程的系统调用、获得和设置进程属性的系统调用等。
文件操作类系统调用
对文件进行操纵的系统调用数量较多,有创建文件、打开文件、关闭文件、读文件、写文件、创建一个目录、建立目录、移动文件的读/写指针、改变文件的属性等。
进程通信类系统调用
该类系统调用被用在进程之间传递消息和信号。
设备管理类系统调用
该类系统调用被用于请求和释放有关设备,以及启动设备操作等。
信息维护类系统调用
操作系统中还提供了一类有关信息维护的系统调用。用户可利用这类系统调用来获得当前时间和日期、设置文件访问和修改时间、了解系统当前的用户数、操作系统版本号、空闲内存和磁盘空间的大小等。
不同的系统提供有不同的系统调用。一般,每个系统为用户提供几十到几百条系统调用。
系统调用命令是作为扩充机器指令,增强系统的功能,方便用户使用而提供的。因此,在一些计算机系统中,把系统调用命令称为“广义指令”。但“广义指令”和机器指令在性质上是不同的。机器指令是由硬件线路直接实现的,而“广义指令”则是由操作系统所提供的一个或多个子程序模块,即软件实现的。从用户角度来看,操作系统提供了这些“广义指令”,也就是系统调用指令,就好像扩大了机器的指令系统,增强了处理器的功能。用户不仅可以使用硬件提供的机器指令,也可以直接使用软件,即操作系统提供的广义指令这就如同为用户提供了一台功能更强,使用更方便的处理器,即实现了处理器性能上的扩充。为了区别于真实的物理处理器,我们称它为“虚处理器”。
系统调用与库函数、API、内核函数的关系
库函数是在C语言程序设计中,所有匹配标准的头文件( Head File)的集合,以及常用的函数库实现程序。应用程序接口( applicatio Programming Interface, API),又称为应用编程接口,就是软件系统不同组成部分衔接的约定,它是提供给应用程序调用使用的代码。库函数与API的主要目的是让应用程序开发人员得以调用一组例程功能,而无须考虑其底层的源代码为何或理解其内部工作机制的细节。在编写应用程序时,用户使用库函数和AP来完成具体功能的实现。
通常应用程序是使用API在用户空间里实现的,而不是直接使用系统调用实现的,用户使用库函数和AP来完成系统调用的执行,这二者相当于是系统调用的封装。系统调用是操作系统提供给用户程序调用的一组“特殊”接口,用户程序可以通过这组“口来获得操作系统内核提供的服务。