学习目录
1. Linux学习路径
2. Linux内核体系结构
3. 系统调用简介
3.1 系统调用分类简介
3.1.1 进程管理
3.1.2 内存管理
3.1.3 文件管理
3.1.4 信号处理
3.1.5 进程间通信
3.1.6 网络通信
3.2 系统调用与Glibc
1. Linux学习路径
2. Linux内核体系结构
说明1:统一的服务提供方式
① 从服务使用者的角度,应用程序只能通过系统调用的方式使用Linux内核提供的服务
② 从服务提供者的角度,Linux内核各子系统提供不同的系统调用供用户使用,示例如下
说明2:注意内核子系统之间的关系,例如,
① 进程管理子系统需要内存管理子系统分配内存
② 文件子系统屏蔽各种设备的差异,向用户提供统一的系统调用接口
3. 系统调用简介
3.1 系统调用分类简介
3.1.1 进程管理
说明:先拷贝再修改的策略
① 在Linux中,要创建一个新的进程,需要一个老的进程调用fork来实现,其中老的进程叫做父进程,新的进程叫做子进程
② 当父进程调用fork创建进程的时候,子进程将各个子系统为父进程创建的数据结构全部拷贝一份,甚至连程序代码也拷贝过来
然后fork系统调用在父进程和子进程中返回不同的值,父进程中返回子进程PID;子进程中返回0,以此作为区分
如果是父进程则接着做原来的工作;如果是子进程则调用execve系统调用来执行另一个程序,此时子进程和父进程就彻底分道扬镳了,也即产生了一个分支(fork)
③ Linux启动时会创建一个所有用户进程的祖宗进程,这也是系统中唯一一个没有通过fork或kernel_thread创建的线程
④ 父进程可以使用waitpid系统调用获取子进程是否运行完成及其完成状态
3.1.2 内存管理
说明1:每个进程都有自己的进程内存空间,相互之间不干扰
说明2:进程内存空间分段
代码段 / 数据段 / 栈 / 堆
说明3:实际分配物理内存的时机
进程虚拟内存空间是很大的,32位CPU为4GB(64位CPU则更大),但是物理内存实际可能没有这么多
所以只有进程要去使用内存的时候,才会使用内存管理的系统调用来登记,说明自己马上要使用内存,希望操作系统分配一部分内存给他。但是这并不代表真的就对应到物理内存,只有真正写入数据时,发现没有对应的物理内存,才会触发一个中断,实际分配物理内存
说明4:brk & mmap系统调用
① 这2个系统调用用于在堆中分配内存
② 当分配的内存数量较小时,使用brk系统调用,会和原来的堆数据连在一起
③ 当分配的内存数量比较大时,使用mmap系统调用,会重新划分一片区域
3.1.3 文件管理
说明1:文件保存的要点:介质与格式
说明2:文件操作:创建、打开、关闭、读写
说明3:Linux中一切皆文件
文件打开后,Linux会分配一个文件描述符(File Descriptor),这是一个整数,后续的文件系统调用均需要该文件描述符
一切皆文件的优势,就是统一了操作入口
3.1.4 信号处理
说明1:信号处理用于处理异常情况
说明2:常见信号
① <ctrl> + c发送SIGINT信号
② 非法内存访问
③ 硬件故障
④ 用户进程调用kill函数向另一个进程发送信号
说明3:信号的不同处理方式
① 忽略
② 默认方式
③ signal / sigaction注册handler
注意:有些信号是不能忽略的,比如SIGKILL / SIGSTOP
3.1.5 进程间通信
说明1:消息队列
① 适合交互一段不是很长的数据
② 消息队列在内核中
说明2:共享内存
① 适合交互一段很长的数据
② 共享内存本身不提供同步机制
说明3:信号量
提供互斥与同步机制
3.1.6 网络通信
说明1:网络服务通过套接字socket提供服务
说明2:socket的名字可以理解为"插口"或"插槽",可以想象一根网线一端插在客户端,一端插在服务端
说明3:可以通过socket系统调用建立一个socket,socket也是一个文件,也有一个文件描述符,也可以通过读写函数进行通信
补充:查看源码中的系统调用
Linux内核提供的系统调用包含在include/linux/unistd.h中,该文件只有一行,用于包含基于架构的实际头文件
在ARM32架构中,实际包含的是arch/arm/include/asm/unistd.h文件
3.2 系统调用与Glibc
① Glibc是Linux下使用的开源的标准C库,是由GNU发布的libc库
② Glibc为程序员提供了丰富的API,除了例如字符串处理、数学运算等用户态服务之外,最重要的是封装了操作系统提供的系统服务,即系统调用的封装
③ 每个特定的系统调用对应至少一个Glibc封装的函数
e.g. 打开文件的系统调用sys_open对应的是Glibc中的open函数
④ 有些API可能调用多个系统调用
e.g. Glibc提供的printf函数会调用sys_open、sys_mmap、sys_write、sys_close等系统调用
⑤ 有时候多个API也可能对应同一个系统调用
e.g. Glibc下实现的malloc、calloc、free等函数用来分配和释放内存,都利用了内核的sys_brk系统调用
说明:strace命令可以用来跟踪进程执行时使用的系统调用和接收的信号
原文链接:https://blog.youkuaiyun.com/chenchengwudi/article/details/115420538