【操作系统-6】系统调用
1、何为系统调用?
系统调用(System Call)是用户程序与操作系统内核之间的接口。通过系统调用,用户程序可以请求操作系统执行一些特权操作或访问硬件资源,这些操作通常是普通应用程序无法直接执行的。系统调用是操作系统提供的服务,是操作系统对外部用户程序的主要接口。
在现代操作系统中,系统调用通常提供对文件操作、进程控制、内存 管理、设备管理等核心功能的访问。
2、系统调用的作用
系统调用的主要作用包括:
- 访问操作系统资源:用户应用程序需要通过系统调用来访问操作系统的底层资源,如文件、网络、内存和硬件设备等。
- 提供安全性和隔离性:操作系统通过系统调用实现内核和用户空间的隔离。用户程序无法直接访问硬件或执行特权操作,这有助于防止用户程序意外或恶意破坏系统资源。
- 实现进程间通信:系统调用为进程提供了各种方式的通信机制,如信号、管道、共享内存、消息队列等。
- 简化程序开发:应用程序通过系统调用接口与操作系统交互,避免直接管理硬件,简化了程序开发。
3、系统调用与库函数的区别
虽然系统调用和库函数在程序中都起着至关重要的作用,但它们有明显的区别。
(1)定义与位置:
- 系统调用:是操作系统内核提供的服务接口,通常位于操作系统的内核空间。应用程序通过系统调用与操作系统内核交互,进行特权操作(如读写文件、进程管理、内存管理等)。
- 库函数:是由C标准库或其他库提供的函数,通常位于用户空间。库函数的作用是简化程序的开发,封装了常用的操作,提供了对系统调用的更高层次的抽象。
(2)功能:
- 系统调用:直接与操作系统的内核交互,能够执行硬件级别或系统级的任务,如文件操作、网络通信、内存管理、进程创建等。
- 库函数:提供一系列常见的功能,通常会封装多个系统调用,并对外提供简单易用的接口。例如,
fopen函数是C库函数,它可能调用open系统调用来打开文件。
(3)性能和执行方式:
- 系统调用:通常是低级操作,直接与内核交互。调用系统调用时,程序会从用户模式切换到内核模式,进行上下文切换。由于涉及到模式切换,系统调用的开销较大。
- 库函数:库函数通常运行在用户模式,调用库函数不需要切换到内核模式,除非库函数本身内部调用了系统调用。因此,库函数的执行速度通常比系统调用快,但库函数的功能较为抽象,通常依赖系统调用实现具体的操作。
(4)调用的复杂度:
- 系统调用:调用系统调用需要通过特殊的指令(如syscall或int指令)来触发系统调用,并由操作系统的内核来处理请求。系统调用通常涉及更多的权限检查、上下文切换等。
-
库函数:调用库函数通常是简单的函数调用,它们封装了对系统调用的实现。应用程序只需要调用库函数,而不需要直接操作内核接口。
示例:
- 系统调用示例:
open(),read(),write(),fork(),exec(),mmap()。 - 库函数示例:
fopen(),fread(),fwrite(),malloc(),printf()。
4、系统调用的过程
系统调用的实现涉及用户空间和内核空间之间的切换。具体的过程通常包括以下几个步骤:
(1)用户态到内核态的切换
当用户程序需要执行系统调用时,会发生从用户态切换到内核态。这个过程包括:
- 程序调用一个系统调用的接口(如read(),write()等)。对于C语言库函数,它会调用系统调用的封装函数。
- 系统调用需要通过一种机制通知操作系统内核进行处理。在x86架构上,系统调用通常通过“syscall指令或int 0x80指令”来触发。
(2)上下文切换
当系统调用被触发时,CPU会进行上下文切换,保存当前用户程序的执行状态,并加载系统调用的执行上下文。此时,操作系统内核将接管控制权,开始执行系统调用。
- 操作系统内核首先通过中断向量来定位相应的系统调用处理程序。
- 然后根据系统调用的类型(如文件操作、内存管理、进程控制等),内核会执行相应的系统调用处理逻辑。
(3)内核处理系统调用
操作系统内核执行实际的系统调用功能。例如,如果用户请求读取文件,内核会访问文件系统 ,查找文件内容,进行必要的错误检查(如文件权限、文件存在性等),然后将结果返回给用户程序。
- 如果系统调用涉及到硬件操作(如磁盘I/O、网络通信等),内核会与硬件交互,通过驱动程序进行实际操作。
- 如果系统调用是进程控制类(如fork()、exec()等),内核会执行调度、创建、销毁进程等操作。
(4)返回用户态
当系统调用完成后,内核会将执行结果返回给用户程序,并将程序的状态恢复为系统调用之前的状态。此时,程序会从内核态切换回用户态,继续执行。
- 系统调用返回的结果(如文件内容、进程ID等)将传递给调用它的用户程序。
- 恢复现场后,CPU会从用户程序的下一条指令继续执行,完成整个系统调用过程。
(5)上下文切换的开销
系统调用涉及从用户态到内核态的切换,通常伴随着上下文切换。上下文切换会导致一些额外的开销,如保存和恢复寄存器的值、内存管理等。为了提高性能,操作系统会通过优化机制(如系统调用缓存 、减少系统调用次数等)来尽量减少上下文切换的开销。
5、常见调用
以下是一些常见的系统调用及其功能:
- open():打开文件,并返回文件描述符。
- read():从文件中读取数据。
- write():向文件中写入数据。
- fork():创建一个新的进程。
- exec():执行一个新的程序。
- mmap():内存映射文件到内存中。
- ioctl():设备控制。
- kill():发送信号给进程。
- exit():退出程序。
总结
系统调用是用户程序与操作系统内核之间的接口,允许程序请求操作系统执行特权操作或访问硬件资源。
系统调用与库函数的区别:系统调用直接与内核交互,执行特权操作,而库函数封装了系统调用,提供更高层次的抽象。系统调用通常涉及更高的开销和复杂的上下文切换。
系统调用过程:用户程序发起系统调用,CPU从用户态切换到内核态,内核执行系统调用并返回结果,最后切换回用户态。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)