目录
一、系统调用和库函数的区别" >一、系统调用和库函数的区别
库函数
四、系统调用和中断的联系" >四、系统调用和中断的联系
首页 后端开发 PHP问题 系统调用的目的是什么

系统调用的目的是什么

Jul 16, 2020 pm 05:44 PM
系统调用

系统调用的目的是:请求系统服务。操作系统不允许用户直接操作各种硬件资源,因此用户程序只能通过系统调用的方式来请求内核为其服务,间接地使用各种资源。

系统调用的目的是什么

由操作系统提供的功能,通常应用程序本身是无法实现的。例如对文件进行操作,应用程序必需通过系统调用才能做到,因为只有操作系统才具有直接管理外围设备的权限。又如进程或线程间的同步互斥操作,也必需经由操作系统对内核变量进行维护才能完成。

从下到上看一个完整的计算机系统:物理硬件->OS内核->OS服务->应用程序。这里的OS内核起到了“承上启下”的关键作用,向下管理物理硬件,向上为操作系统服务和应用程序提供接口,这里的接口就是系统调用了。

应用程序的进程通常在user模式下运行,当它调用一个系统调用时,进程进入kernel模式,执行的是kernel内部的代码,从而具有执行特权指令的权限,完成特定的功能。换句话说,系统调用是应用程序主动进入操作系统内核的入口。

一、系统调用和库函数的区别

库函数

顾名思义是把函数放到库里,是把一些常用到的函数编完放到一个文件里,供别人用。别人用的时候把所在的文件名用#include<>加到里面就可以了,一般放到lib文件里。

库函数主要由两方面提供:一是操作系统提供的;另一类是由第三方提供的。

  • 系统提供的这些函数把系统调用进行封装或者组合,可以实现更多的功能,这样的库函数能够实现一些对于内核来说比较复杂的操作。比如read函数根据参数,直接就能读文件,而背后隐藏的文件比如在那个磁道,那个扇区,加载到那个内存,是程序员不必关心的问题。这些操作里面也包含了系统调用。比如write()这个系统函数,会调用同名的系统调用,来完成写入操作。

  • 对于第三方库,其实和系统库一样,只是他直接利用系统调用的可能性要小一些,而是系统提供的API接口来是实现。比如printf,实际上调用了write()这个系统函数。 第三方库函数大部分是对系统函数的封装。

系统调用和库函数的联系:

事实上,系统调用所提供给用户的是直接而纯碎的高级服务,如果想要更加人性化,具有更符合特定情况的功能,那么就要我们用户自己定义,因此衍生了库函数,它把部分系统调用包装起来。比如当我们要用C语言打印一句话的时候,如果没有用到库函数printf,那么我们就需要自己实现就需要调用putc()和write()等这样一些系统函数。显得比较麻烦,所以系统调用是为了方便使用操作系统的接口,而库函数则是为了人们编程的方便。

例如,在Linux操作系统下,C语言的库函数printf,实际上使用了write系统调用;而库函数strcpy(字符串拷贝)却没有使用任何系统调用。另外,一个系统的系统调用接口通常是能够完成所有必需功能的最小集合,可能存在多个库函数对同一个系统调用进行封装。例如,在Linux中,malloc、calloc和free三个库函数底层都是调用brk系统调用完成的。

应用程序、库函数和系统调用的关系如下图所示:

1.gif

系统调用和库函数的区别:

库函数的调用是语言或者应用程序的一部分,而系统调用则是操作系统的一部分。

系统调用是应用程序与内核交互的接口。人们在长期的编程中发现使用系统函数有个重大的缺点,那就是程序的移植性。例如linux提供的系统调用的函数和windows就不一样。

库函数调用则是面向应用开发的,相当于应用程序的api,采用这样的方式有很多原因:

  • 双缓冲技术;(库函数和系统调用两层缓冲,减少系统调用次数)
  • 移植性(封装了不同操作系统的系统函数,对外接口一致)
  • 底层调用本身存在的一些缺陷;
  • 让api也可以有了级别和专门的工作面向;

二、CPU的内核模式和用户模式

通常,处理器设有两种模式:“用户模式”与“内核模式”,通过一个标签位来鉴别当前正处于什么模式。内核模式可以运行所有指令,包括特权指令(主要是一些硬件管理的指令,例如修改基址寄存器内容的指令) ,而用户模式不能执行特权指令。这样的设计主要为了安全问题,即由操作系统负责管理硬件,避免上层应用因错误设计而导致硬件问题。

既然只有操作系统能直接操作硬件,操作系统有必要提供接口来为应用程序提供使用硬件功能的入口,这些接口就被称为系统调用。

当操作系统接收到系统调用请求后,会让处理器进入内核模式,从而执行诸如I/O操作,修改基址寄存器内容等指令,而当处理完系统调用内容后,操作系统会让处理器返回用户模式,来执行用户代码。

对应CPU的内核模式和用户模式,进程运行的状态分为管态(核心态)和目态(用户态)。具体请看文章:操作系统--用户态和核心态

四、系统调用和中断的联系

中断(Interrupt)通常是指在CPU内部或外部发生了某个待处理的事件,从而CPU必需改变当前指令的执行顺序去处理这类事件。在介绍中断和系统调用的关系之前,下面先把中断做一个分类。

中断可以大体分为两大类:

  • Asynchronous interrupts(外中断): 由CPU外部的其它硬件产生,说这类中断是异步的,意思是中断信号可以在任意时间发射,与CPU本身的时钟节拍没有关系。如时钟中断,硬盘读写服务请求中断等。

  • Synchronous interrupts(内中断/异常):在CPU内部产生,说这类中断是同步的,意思是中断信号的发射时间一定在当前指令执行结束之后。一般来自CPU的内部事件或程序执行中的事件,如非法操作码、地址越界、浮点溢出等。

Synchronous interrupts (异常)又分为以下若干类:

  • Processor-detected exceptions:处理器在执行指令时检测到的中断,如除零操作。

  • Faults:发生了某个异常条件,但异常条件被消除后,原来的程序流程可以继续执行而不受任何影响,如缺页异常。注意触发中断的指令会被重新执行。

  • Traps:由陷入指令引起的中断,通常用于程序调试。

  • Aborts:CPU内部有重要错误发生,例如硬件错误或系统表值出现错误。一旦这种中断发生,错误将不可恢复,只能将当前进程终止。

  • Programmed exceptions:也称为 software interrupts (软中断) ,由程序员的代码主动发起的中断,用来实现系统调用。如在Linux中,就是用int 0x80指令实现系统调用。

至此,我们发现了中断与系统调用的关系:系统调用是一种特殊的中断类型(软中断)

五、内核对于系统调用的处理

在x86的机器中,用一个8bit的数字(0~255)来区分各种中断,这个数字被称为中断向量(vector)。其中一个中断向量,即128 (0x80),专门被用于执行系统调用。

在Linux系统中,存有一个系统表,叫做Interrupt DescriptorTable,简称IDT。IDT表共有256项,存放了从中断向量到相应处理例程(interrupt or exceptionhandler)的映射关系。当某个中断发生时,CPU从IDT表中查找到相应的处理例程的地址来执行。

系统调用的处理例程在IDT表中占有一项。这一项是在trap_init函数中被初始化的,如下:set_system_gate(SYSCALL_VECTOR,&system_call);。如前所述,上面代码中的SYSCALL_VECTOR的值是128。

当系统调用发生时,通过中断机制,系统调用例程system_call被调用。它的执行过程大概分为4个步骤:

1、从寄存器中取出系统调用号和输入参数,然后将这些寄存器的值压入kernel栈中。根据系统调用号查找系统调用分派表(system call dispatch table),找到系统调用服务例程(一个内核函数)。

2、调用查到的系统调用服务例程。

3、将系统调用服务例程的返回值出栈,重新保存在寄存器中。

上面描述的系统调用例程system_call在kernel空间中执行。在执行前,系统调用号和输入参数已经存入了寄存器,这个存入过程由user空间的代码完成。实际上,如同第一节所讲,每个真正的系统调用基本上都有一个封装它的库函数,一般是在这个库函数中完成系统调用号和输入参数的保存动作。当系统调用例程system_call执行完毕后,返回值通过寄存器再传回user空间的库函数。

以上是系统调用的目的是什么的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
2 周前 By 尊渡假赌尊渡假赌尊渡假赌
仓库:如何复兴队友
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒险:如何获得巨型种子
4 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

PHP数组去重有哪些最佳实践 PHP数组去重有哪些最佳实践 Mar 03, 2025 pm 04:41 PM

本文探讨了有效的PHP阵列重复数据删除。 它将内置功能与自定义hashmap方法进行比较,例如基于数组大小和数据类型的性能权衡。 最佳方法取决于Profili

PHP数组去重需要考虑性能损耗吗 PHP数组去重需要考虑性能损耗吗 Mar 03, 2025 pm 04:47 PM

本文分析了PHP阵列重复数据删除,突出了幼稚方法的性能瓶颈(O(n²))。 它使用Array_unique()探索具有自定义功能,SplobjectStorage和Hashset实现的有效替代方案

PHP数组去重可以利用键名唯一性吗 PHP数组去重可以利用键名唯一性吗 Mar 03, 2025 pm 04:51 PM

本文使用关键唯一性探讨了PHP阵列重复数据删除。 虽然不是直接的重复删除方法,但是利用钥匙唯一性可以通过将值映射到键,覆盖重复项来创建具有唯一值的新数组。 这个AP

如何在PHP中实现消息队列(RabbitMQ,REDIS)? 如何在PHP中实现消息队列(RabbitMQ,REDIS)? Mar 10, 2025 pm 06:15 PM

本文使用RabbitMQ和Redis详细介绍了PHP中的消息队列。 它比较了它们的体系结构(AMQP与内存),功能和可靠性机制(确认,交易,持久性)。设计的最佳实践,错误

最新的PHP编码标准和最佳实践是什么? 最新的PHP编码标准和最佳实践是什么? Mar 10, 2025 pm 06:16 PM

本文研究了当前的PHP编码标准和最佳实践,重点是PSR建议(PSR-1,PSR-2,PSR-4,PSR-12)。 它强调通过一致的样式,有意义的命名和EFF提高代码的可读性和可维护性

PHP数组去重有哪些优化技巧 PHP数组去重有哪些优化技巧 Mar 03, 2025 pm 04:50 PM

本文探讨了针对大型数据集的优化PHP阵列重复数据删除。 它检查了Array_unique(),array_flip(),splobjectStorage和Pre-Sorting等技术,以比较它们的效率。 对于大量数据集,它建议块,数据

我如何处理PHP扩展和PECL? 我如何处理PHP扩展和PECL? Mar 10, 2025 pm 06:12 PM

本文详细介绍了安装和故障排除PHP扩展,重点是PECL。 它涵盖安装步骤(查找,下载/编译,启用,重新启动服务器),故障排除技术(检查日志,验证安装,

如何使用反射分析和操纵PHP代码? 如何使用反射分析和操纵PHP代码? Mar 10, 2025 pm 06:12 PM

本文解释了PHP的反射API,可以实现运行时检查和对类,方法和属性的操纵。 它详细介绍了常见用例(文档生成,ORM,依赖注入)和针对绩效垂涎的警告

See all articles