欢迎来到天天文库
浏览记录
ID:30428341
大小:91.87 KB
页数:15页
时间:2018-12-29
《指定恰当的系统调用》由会员上传分享,免费在线阅读,更多相关内容在应用文档-天天文库。
1、指定恰当的系统调用为了和用户空间上运行的进程进行交互,内核提供了一组接口。透过该接口,应用程序可以访问硬件设备和其他操作系统资源。这组接口在应用程序和内核之间扮演了使者的角色,应用程序发送各种请求,而内核负责满足这些请求(或者让应用程序暂时搁置)。实际上提供这组接口主要是为了保证系统稳定可靠,避免应用程序恣意妄行,惹出大麻烦。系统调用在用户空间进程和硬件设备之间添加了一个中间层。该层主要作用有三个。第一,它为用户空间提供了一种硬件的抽象接口。举例来说,当需要读些文件的时候,应用程序就可以不去管磁盘类
2、型和介质,甚至不用去管文件所在的文件系统到底是哪种类型。第二,系统调用保证了系统的稳定和安全。作为硬件设备和应用程序之间的中间人,内核可以基于权限和其他一些规则对需要进行的访问进行裁决。举例来说,这样可以避免应用程序不正确地使用硬件设备,窃取其他进程的资源,或做出其他什么危害系统的事情。第三,在第3章中曾经提到过,每个进程都运行在虚拟系统中,而在用户空间和系统的其余部分提供这样一层公共接口,也是出于这种考虑。如果应用程序可以随意访问硬件而内核又对此一无所知的话,几乎就没法实现多任务和虚拟内存,当然也
3、不可能实现良好的稳定性和安全性。在Linux中,系统调用是用户空间访问内核的惟一手段;除异常和陷入外,它们是内核惟一的合法入口。实际上,其他的像设备文件和/proc之类的方式,最终也还是要通过系统调用进行访问的。而有趣的是,Linux提供的系统调用却比大部分操作系统都少得多。本章重点强调Linux系统调用的规则和实现方法。5.1API、POSIX和C库一般情况下,应用程序通过应用编程接口(API)而不是直接通过系统调用来编程。这点很重要,因为应用程序使用的这种编程接口实际上并不需要和内核提供的系统调
4、用对应。一个API定义了一组应用程序使用的编程接口。它们可以实现成一个系统调用,也可以通过调用多个系统调用来实现,而完全不使用任何系统调用也不存在问题。实际上,API可以在各种不同的操作系统上实现,给应用程序提供完全相同的接口,而它们本身在这些系统上的实现却可能迥异。在Unix世界中,最流行的应用编程接口是基于POSIX标准的。从纯技术的角度看,POSIX是由IEEE的一组标准组成,其目标是提供一套大体上基于Unix的可移植操作系统标准。Linux是与POSIX兼容的。POSIX是说明API和系统调
5、用之间关系的一个极好例子。在大多数Unix系统上,根据POSIX而定义的API函数和系统调用之间有着直接关系。实际上,POSIX标准就是仿照早期Unix系统的界面建立的。另一方面,许多操作系统,像WindowsNT,尽管和Unix没有什么关系,也提供了与POSIX兼容的库。Linux的系统调用像大多数Unix系统一样,作为C库的一部分提供如图5-1所示。如图5-1所示C库实现了Unix系统的主要API,包括标准C库函数和系统调用。所有的C程序都可以使用C库,而由于C语言本身的特点,其他语言也可以很方
6、便地把它们封装起来使用。此外,C库提供了POSIX的绝大部分API。图5-1调用printf()函数时,应用程序、C库和内核之间的关系从程序员的角度看,系统调用无关紧要;他们只需要跟API打交道就可以了。相反,内核只跟系统调用打交道;库函数及应用程序是怎么使用系统调用不是内核所关心的。但是,内核必须时刻牢记系统调用所有潜在的用途并保证它们有良好的通用性和灵活性。关于Unix的界面设计有一句通用的格言"提供机制而不是策略"。换句话说,Unix的系统调用抽象出了用于完成某种确定目的的函数。至于这些函数怎
7、么用完全不需要内核去关心。(区别对待机制(mechanism)和策略(policy)是Unix设计中的一大亮点。大部分的编程问题都可以被切割成两个部分:"需要提供什么功能"(机制)和"怎样实现这些功能"(策略)。如果由程序中的独立部分分别负责机制和策略的实现,那么开发软件就更容易,也更容易适应不同的需求。系统调用(在Linux中常称作syscalls)通常通过函数进行调用。它们通常都需要定义一个或几个参数(输入)而且可能产生一些副作用,例如写某个文件或向给定的指针拷贝数据等等。系统调用还会通过一个l
8、ong类型的返回值来表示成功或者错误。通常,但也不绝对,用一个负的返回值来表明错误。返回一个0值通常(当然仍不是绝对的)表明成功。Unix系统调用在出现错误的时候会把错误码写入errno全局变量。通过调用perror()库函数,可以把该变量翻译成用户可以理解的错误字符串。当然,系统调用最终具有一种明确的操作。举例来说,如getpid()系统调用,根据定义它会返回当前进程的PID。内核中它的实现非常简单:asmlinkagelongsys_getpid(void){re
此文档下载收益归作者所有