简 述: 对于 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 学习,附学习由浅入深的目录。