Linux系统调用与用户编程接口

参考文献 华清远见《FS-MP1A开发教程-2022-04-01》

1. 系统调用

​ 操作系统负责管理和分配所有的计算机资源。为了更好地服务于应用程序,操作系统提供了一组特殊接口—系统调用。通过这组接口,用户程序可以使用操作系统内核提供的各种功能,如分配内存、创建进程、实现进程之间的通信等。
为什么不允许程序直接访问计算机资源?答案是不安全。单片机开发中,由于不需要操作系统,所以开发人员可以编写代码直接访问硬件。而在嵌入式系统中通常都要运行操作系统,程序访问资源的方式就发生了改变。操作系统基本上都支持多任务,即同时可以运行多
个程序。如果允许程序直接访问系统资源,肯定会带来很多问题。因此,所有软硬件资源的管理和分配都由操作系统负责。程序要获取资源(如分配内存、读写串口)必须通过操作系统来完成,即用户程序向操作系统发出服务请求,操作系统收到请求后执行相关的代码来处
理。
用户程序向操作系统提出请求的接口就是系统调用。所有的操作系统都会提供系统调用接口,只不过不同的操作系统提供的系统调用接口各不相同。Linux 系统调用接口非常精简,它继承了 UNIX 系统调用中最基本和最有用的部分。这些系统调用按照功能大致可分为进程控制、进程间通信、文件系统控制、存储管理、网络管理、套接字控制、用户管理等。

2. 用户程序编程接口

​ 前面提到利用系统调用接口程序可以访问各种资源,但在实际开发中程序并不直接使用系统调用接口,而是使用用户程序编程接口API)。

​ 为什么不直接使用系统调用接口呢?原因如下。
系统调用接口功能非常简单,无法满足程序的需求。
不同操作系统的系统调用接口不兼容,程序移植时工作量大。

​ 用户程序编程接口通俗的解释就是各种库(最重要的就是 C 库)中的函数。为了提高开发效率,C 库中实现了很多函数。这些函数实现了常用的功能,供程序员调用。这样一来,程序员不需要自己编写这些代码,直接调用库函数就可以实现基本功能,提高了代码的复用率。使用用户程序编程接口还有一个好处:程序具有良好的可移植性。几乎所有的操作系统上都实现了 C 库,所以程序通常只需要重新编译一下就可以在其他操作系统下运行。

用户程序编程接口(API)在实现时,通常都要依赖系统调用接口。例如,创建进程的API 函数 fork()对应于内核空间的 sys_fork()系统调用。很多 API 函数需要通过多个系统调用来完成其功能。还有一些 API 函数不需要调用任何系统调用。在 Linux 中,用户程序编程接口(API)遵循了在 UNIX 中最流行的应用编程界面标准—POSIX 标准。POSIX 标准是由 IEEE 和 ISO/IEC 共同开发的标准系统,该标准基于当时的UNIX 实践和经验,描述了操作系统的系统调用编程接口(实际上就是 API),用于保证应用程序可以在源代码一级上在多种操作系统上移植运行。这些系统调用编程接口主要是通过 C库(libc)实现的。

3. Linux标准IO

​ 标准 I/O 指的是 ANSI C 中定义的用于 I/O 操作的一系列函数。
​ 只要操作系统中安装了 C 库,标准 I/O 函数就可以调用。换句话说,如果程序中使用的是标准 I/O 函数,那么源代码不需要修改就可以在其他操作系统下编译运行,具有更好的可移植性。
​ 除此之外,使用标准 I/O 可以减少系统调用的次数,提高系统效率。标准 I/O 函数在执行时也会用到系统调用。在执行系统调用时,Linux 必须从用户态切换到内核态,处理相应的请求,然后再返回到用户态。如果频繁地执行系统调用会增加系统的开销。为了避免这种
情况,标准 I/O 使用时在用户空间创建缓冲区读写时先操作缓冲区,在合适的时机再通过系统调用访问实际的文件,从而减少了使用系统调用的次数。

3.1 流的含义

​ 标准 I/O 的核心对象就是流。当用标准 I/O 打开一个文件时,就会创建一个 FILE 结构体描述该文件(或者理解为创建一个 FILE 结构体和实际打开的文件关联起来)。我们把这个FILE 结构体形象地称为流。标准 I/O 函数都基于流进行各种操作。

  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2022-2024 lk
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信