Linux系统编程 ---系统调用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/shanghx_123/article/details/83153155

系统调用

计算机系统的各种硬件资源是有限的,在现代多任务操作系统上同时运行的多个进程都需要访问这些资源,为了更好的管理这些资源进程是不允许直接操作的,所有对这些资源的访问都必须有操作系统控制。也就是说操作系统是使用这些资源的唯一入口,而这个入口就是操作系统提供的系统调用 (System Call)。 在Linux中系统调用是用户空间访问内核的唯一手段,除异常和陷入外,他们是内核唯一的合法入口。
这些系统调用按功能大致可分为如下几类:
设备管理:完成设备的请求或释放,以及设备启动等功能。
文件管理:完成文件的读、写、创建及删除等功能。
进程控制: 完成进程的创建、撤销、阻塞及唤醒等功能。
进程通信: 完成进程之间的消息传递或信号传递等功能。
内存管理: 完成内存的分配、回收以及获取作业占用内存区大小及始址等功能。

系统调用说的也是操作系统提供给用户程序调用的一组 “特殊”接口。用户程序可以通过这组“特殊”接口来获得操作系统内核提供的服务,比如用户可以通过文件系统相关的调用请求系统打开文件、关闭文件或读写文件,可以通过时钟相关的系统调用获得系统时间或设置定时器等。

从逻辑上来说,系统调用可被看成是一个内核与用户空间程序交互的接口——它好比一个中间人,把用户进程的请求传达给内核,待内核把请求处理完毕后再将处理结果送回给用户空间。
这里我们举个例子来理解: 如果说你是一个闷骚且害羞的程序员, 那shell就像媒婆,操作系统内核就是你们村头漂亮的且有让你心动的MM小红。你看上了小红,但是又不好意思直接表白,那就让你你家人找媒婆帮你提亲,所有的事情你都直接跟媒婆沟通,由媒婆转达你的意思给小红,而我们找到媒婆姓王, 所以我们叫它王婆,它对应我们常使用的bash。

在这里插入图片描述
系统服务之所以需要通过系统调用来提供给用户空间的根本原因是为了对系统进行“保护”, 因为我们知道Linux的运行空间分为内核空间与用户空间,它们各自运行在不同的级别中,逻辑上相互隔离。所以用户进程在通常情况下不允许访问内核数据,也无法使用内核函数,它们只能在用户空间操作用户数据,调用用户空间函数。比如我们熟悉的“hello world”程序(执行时)就是标准的用户空间进程,它使用的打印函数printf就属于用户空间函数,打印的字符“hello word”字符串也属于用户空间数据。

但是很多情况下,用户进程需要获得系统服务(调用系统程序),这时就必须利用系统提供给用户的“特殊接口”——系统调用了,它的特殊性主要在于规定了用户进程进入内核的具体位置;换句话说,用户访问内核的路径是事先规定好的,只能从规定位置进入内核,而不准许肆意跳入内核。有了这样的陷入内核的统一访问路径限制才能保证内核安全无误。我们可以形象地描述这种机制:作为一个游客,你可以买票要求进入野生动物园,但你必须老老实实地坐在观光车上,按照规定的路线观光游览。当然,不准下车,因为那样太危险,不是让你丢掉小命,就是让你吓坏了野生动物。

系统调用的实现

系统调用是属于操作系统内核的一部分的,必须以某种方式提供给进程让它们去调用。CPU 可以在不同的特权级别下运行,而相应的操作系统也有不同的运行级别,用户态和内核态。运行在内核态的进程可以毫无限制的访问各种资源,而在用户态下的用户进程的各种操作都有着限制,比如不能随意的访问内存、不能开闭中断以及切换运行的特权级别。显然,属于内核的系统调用一定是运行在内核态下。
关于如何切换到内核态呢?我上篇博客详细介绍过: Linux下如何从用户态切换到内核态?

系统调用和库函数的区别

Linux 下对文件操作有两种方式:系统调用(system call)和库函数调用(Library functions)。

库函数由两类函数组成:

1)不需要调用系统调用

不需要切换到内核空间即可完成函数全部功能,并且将结果反馈给应用程序,如strcpy、bzero 等字符串操作函数。

2)需要调用系统调用

需要切换到内核空间,这类函数通过封装系统调用去实现相应功能,如 printf、fread等。
在这里插入图片描述

资料来源: https://blog.csdn.net/tennysonsky/article/details/45101303

猜你喜欢

转载自blog.csdn.net/shanghx_123/article/details/83153155