简 述: 对于 Linux 学习过程中,有一些基本的知识点、关于系统,以下均是以 32 位系统上的为例的知识点:

  • 虚拟地址空间

  • pcb 和文件描述符

  • C 库 I/O 函数工作流程

  • 标准 c 库函数和 linux 系统函数的区别

[TOC]


本文初发于 “偕臧的小站“,同步转载于此。


编程环境:

  💻: uos20 📎 gcc/g++ 8.3 📎 gdb8.0


虚拟地址空间:

Linux 每一个运行的程序(进程)操作系统都会为其分配一个 0~4G 的地址空间(虚拟地址空间)。

进程:正在运行的程序。

Linux 程序运行理解图:

  • env 查看系统的环境变量
  • static int a = 0; 变量 a 仍然是放在 .bss 区域(其值为0)
  • 栈(局域变量): 从高位 到 低位 生长
  • 堆(new ): 从低位 到 高位 生长
  • MMU(内存管理单元):将 虚拟地址空间(硬盘)的地址, 映射 到 物理内存 里面进行管理和操作。
  • 没有必要研究,大致知道其原理即可。

pcb 和文件描述符表:

  • 进程控制块(PCB): 进程在操作系统中都有一个户口,用于表示这个进程。这个户口操作系统被称为PCB(进程控制块),在 linux 中具体实现是 task_struct 数据结构。

  • 进程就是一个运行当中的程序。 我们在编辑器或 IDE 上写了十几个的.cpp 文本文件,它们组合起来就是一个工程。程序本来是存储在磁盘的,当我们需要执行它的时候,先把他读取到内存当中,再然后放入到寄存器中,最后让cpu执行程序,这个时候程序就变成了一个进程。

  • 每个进程运行的时候都会拿到最多 4G 的虚拟内存。其中 3G 是交给用户的,然后剩下的 1G 内存存储内核的东西了。

  • 文件描述符 表,系统最多可以打开 1024 个文件,其中 0、1、2 依次被 stdin、stdout、stderr 这个给使用了;且这个三个文件描述符所指向的对象都是当前终端,当前终端也可以被看为一个文件 /dev/tty (Linux 下一切皆文件); 其余每打开一个文件,就会申请一个空的、最小的 文件描述符。其就是一个 int 型的数值。eg:此时使用系统 open() 函数打开一个 .txt 文件,printf() 打印其的返回值,会显示是 4。


C 库 I/O 函数工作流程:

  • 由这个图可以思考一个问题🤔?那么是不是使用系统的读写函数,一定比使用 c 库的函数的效率一定高呢❓❓❓

    当然不是;这个的看实际情况的。使用系统的读写函数,就是直接和硬件,直接在磁盘上面读写操作,速度肯定比直接在内存上面读写要慢的多。所以就引发内存块上有缓冲区的机制,内存上面写入多次之后,缓冲区满了后,再一次都写入到磁盘上面的文件。


C 库函数与系统函数的关系:

  • 当调用标准的 C 库函数时候(# include <stdio.h>)的 printf() 时候,它会在里面调用应用层的 weite() 函数,然后应用层实际又是调用 系统的 sys_write(),其系统层实际又是调用驱动层的写函数,而驱动层的函数当然是可以直接操作硬件的(比如显示器🖥)。最后就终端里面看到了一句输出语句函数。

下载地址:

https://github.com/xmuli/linuxExample

欢迎 star 和 fork 这个系列的 linux 学习,附学习由浅入深的目录。