【Linux】浅谈C语言库函数和系统调用接口的关联

前言

我们给出这样一张计算机的层级图:

在这里插入图片描述
可以看到,整个计算机体系分为硬件层和软件层

而在软件层,我们又有内核层与用户层

操作系统是横亘在硬件与用户软件之间的一个软件,对下管理各种硬件,对上为用户软件提供服务。我们可以这样类比

用户 校长
操作系统 辅导员
硬件 学生

我们人要管理好硬件,那么就需要一个懂硬件的帮我们管理硬件,那就是操作系统

但是,为了保证安全,操作系统对人只会开放特定的接口,通过特定的接口,人才可以来对硬件进行特定的管理,这样的接口,就叫做系统调用接口

然而,系统调用接口是比较复杂的,让人每次都使用系统调用接口去管理硬件也太烦了吧,于是,便有一些别有用心的人对于系统调用接口进行了二次封装,封装出了一些更加友好、人性化的接口来供人调用,例如:

  • C语言库函数
  • 命令行解释器
  • 图形化界面

总而言之,这张层级图解释了一切:

在这里插入图片描述

接下来,我们就以Linux操作系统为例,分别看一下系统调用接口和经过二次封装的C语言库函数对于读/写操作的方式

1.系统调用接口

1.考察open, read, write, lseek, close等函数的使用,同时理解文件描述符
2.要求:
2.1 使用代码打开当前路径下的“bite”文件(如果文件不存在在创建文件),向文件当中写入“i like linux!”.
2.2 在从文件当中读出文件当中的内容, 打印到标准输出当中; 关闭文件描述符

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

int main() {
    
    
  int fd = open("bite", O_WRONLY|O_CREAT, 0644);
  const char* buffer = "i like linux\n";
  write(fd, buffer, strlen(buffer));
  close(fd);
  fd = open("bite", O_RDONLY, 0644);
  char output[128] = {
    
    '\0'};
  read(fd, output, 127);
  write(1, output, strlen(output));
  close(fd);
  return 0;
}

在这里插入图片描述

2.C语言库函数

1.考察fopen, fread, fwrite, fseek, fclose等函数的使用
2.要求:
2.1使用代码打开当前路径下的“bite”文件(如果文件不存在在创建文件),向文件当中写入“linux so easy!”.
2.2 在从文件当中读出文件当中的内容, 打印到标准输出当中; 关闭文件流指针

#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main() {
    
    
  FILE* fp = fopen("bite", "w");
  const char* buffer = "linux so easy\n";
  fwrite(buffer, 1, strlen(buffer), fp);
  fclose(fp);
  fp = fopen("bite", "r");
  char output[128] = {
    
    0};
  fread(output, 1, 128, fp);
  fprintf(stdout, "%s", output);
  fclose(fp);
  return 0;
}

在这里插入图片描述

3.总结

我们可以看到,系统调用接口和C语言库函数都能完成读写操作,总的来说:

  1. 在开发角度,操作系统对外表现成一个整体,但是会暴露自己的部分接口,供上层开发使用,这部分由操作系统提供的接口,叫做系统调用。
  2. 系统调用在使用上,功能比较基础,对用户的要求相对也比较高,所以,有心的开发者可以对部分系统调用进行适度封装,从而形成库,有了库,就很有利于更上层用户或者开发者进行二次开发。

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/m0_52640673/article/details/123172350