思维导图
基础指令
目录相关
- ls / pwd / mkdir / rm / cp / mv / cd
文件相关
- touch / cat / more / less / head / tail / gzip / gunzip / zip / unzip / bzip2 / bunzip2 / tar
查找匹配
- find / grep …
权限相关
- 文件权限的表示方法 / umask(权限掩码) / chomd
进程相关
- ps / kill / ipcs / ipcrm
网络
- netsat / ping / route / traceroute / ip / ftp …
其他
- awk / sed / man / ifconfig / cal / data / su / | / >> / > / top / free / disk / df / du
常用工具
系统包管理
- yum
个人编程
vim
-
常见模式
- 插入模式:插入数据 i
- 普通模式:完成命令 Esc
- 底行模式:保存文件 / 查找替换 / 推出编辑 :
-
常见指令
-
光标移动
- hjkl:上下左右 ctrl+F/+B 上下翻页 gg / G 头尾
-
内容操作
- yy :复制 p / P:粘贴 x / dw / dd:删除 u:撤销
-
其他操作
- 自行百度
-
gcc / g++
-
编译流程
-
预处理
- gcc -E 去掉注释,展开代码
-
编译
- gcc -S 语法纠错,将代码解释称汇编代码
-
汇编
- gcc -c 将汇编代码解释成机器语言
-
链接
-
动态链接
- 连接动态库(程序小,依赖动态库的存在)
-
静态链接
- 来凝结静态库(拷贝一份静态库,当静态库多个进程使用时,资源浪费大)
-
-
-
常用命令
- -E / -S / -c / -o / -l / -L / -fPlC / --share / -static / -g
gdb
-
前提
- gcc默认成成release版本程序,使用 -g 生成 debug 版本
-
常见指令
-
调试
- run / start / step / next / until / contir
-
断点
- break / watch / info break / delete / continue
-
查看调用栈
- backtrace
-
项目编程
make / makefile
-
makefile 编写规则
- 目标对象【依赖对象】
- tab 要执行的命令
- $^ 所有依赖对象
- $@ 目标对象
- $< 依赖对象中的第一个
- 目标对象【依赖对象】
-
make 的解释规则
make 在 makefile 中寻找第一个目标对象名称
目标对象名称不存在:报错推出
目标对象名称存在:检测是否有依赖对象
目标对象文件若存在:判断是否有依赖对象名称
有依赖对象名称:认为目标对象已生成,不需要重新生成
没有依赖对象名称:判断依赖对象文件是否存在
存在:判断目标对象文件与依赖对象文件的时间关系
不存在:在makefile继续向下查找依赖对象的生成规则,依赖对象在下一条规则中作为目标对象被生成,进而生成第一个目标对象后退出
目标对象文件不存在:直接执行命令生成 -
伪对象
- .PHONY
git
-
三板斧
- 下载服务器上的代码 :git clone https_addr
- 本地提交 :git push origin
- 服务器分支提交 :git push origin master
进程
冯诺依曼
-
五大硬件单元
- 输入 / 输出 / 内存 / 运算器 / 控制器
- 所有设备都是围绕内存工作的
操作系统
-
管理软件
- 先描述再组织
-
库函数与系统调用接口的关系
- 上下级调用关系 :库函数是对系统调用函数的一层封装
进程概念
-
进程是什么?
- 用户层面 :运行中的程序
- 操作系统层面 :资源分配的最小单位
-
PCB
-
描述一个程序的运行
- linux下PCB是struct task_struct{…}
-
-
描述信息
- 内存指针 / 上下文数据 / 程序计数器 / 标识符pid / 状态 / 优先级 / 记账信息 / IO信息
进程状态
-
运行(包括 运行+就绪) R / 可中断休眠 S / 不可中断休眠 D / 停止 T / 僵死 Z
-
僵尸进程
-
产生原因 : 子进程先于父进程退出,因为要保留推出原因,因此操作系统不能直接释放资源。
-
危害
- 占用资源无法释放
-
-
孤儿进程
-
如何产生
- 父进程先于子进程退出
-
特性
- 运行在后台,父进程成为一号进程
-
环境变量
-
概念
- 存储系统运行环境参数的变量
-
特性
- 全局性(继承),分终端
-
常见的环境变量
- HOME PWD SHELL PATH :作用自查
-
命令
- env / set / echo / export / unset
-
接口
- mian 第三个参数 / 全局变量 environ / getenv()
程序地址空间
-
概念
- 程序地址空间是一个虚拟地址空间 – mm_struct
- 通过页表映射解决通过虚拟地址获得物理地址
-
作用
- 提高内存利用率
- 提供内存访问控制
- 保证进程独立性
操作系统内存管理
-
分页式
- 内存地址构成:段号 + 偏移量
- 段表 ----- 有很多段表项
-
分段式
- 页号 + 页内偏移
- 页表 ----- 有很多页表项
- 虚拟页号 <----> 物理页号
-
段页式
- 段号 + 段内页号 + 页内偏移
- 段表项中包含段内页表起始地址
- 段内页表项中包含物理页号
内存置换算法
- FIFO 先进先出
- LFU 最近最少
- LRU 最近最久
进程控制
进程创建
-
fork / vfork ------- clone
-
创建一个子进程的流程
-
写诗拷贝技术(fork)
操作系统通过复制父进程创建子进程,子进程初始时与父进程指向同一块物理内存区域,当内存数据发生改变时,会为子进程重新开辟内存更新列表。
-
-
代码共享,数据独有 (fork)
-
返回值
进程等待
-
概念
- 等待子进程退出
-
目的
- 获取子进程退出码 / 避免产生僵尸进程
-
接口
-
pid_t wait (int status);
// 等待任意一个子进程退出 -
pid_t waitpid(pid_t pid,int *status,int options);
// 可以等待指定的子进程退出,并且可以设置成非阻塞pid -1 等待任意子进程 options 将 wait(pid)设置成非阻塞
>0 等待指定子进程
status 32位,高16位弃用,低16位 的 高8位 存储返回值,低8位的 高1位 存储 core dump 标志,低七位 存储 异常退出信号值 0 为正常退出,core dump 核心转储:程序异常退出时保存程序运行信息,便于事后调试,默认关闭
-
进程终止
-
推出场景
- 正常退出 符合预期 / 不符合预期
- 异常退出 常见程序崩溃
-
退出方式
- main函数中return 退出进程 推出前刷新缓冲区 函数中return只是退出函数
- 任意位置exit 退出进程 void exit (int status)库函数 退出前刷新缓冲区
程序替换
-
概念
- 替换一个进程正在运行的程序
-
目的
- 让子进程实现其他任务
-
接口
-
exec 函数族
- execl execlp execle ececv ececvp ececve
前五个为库函数 最后一个系统调用函数
- execl execlp execle ececv ececvp ececve
-
-
课外小知识点
- fflush(stdout); 刷新缓冲区
scanf("%[^\n]%*c",tmp); 获取连续字符串
isspace(); 是否是空白字符
wait(NULL); 等待子进程退出
- fflush(stdout); 刷新缓冲区
基础IO
标准库IO接口
- fopen(r/r+/w/w+/a/a+)fseek / fread / fwrite / fclose
系统调用IO接口
- open / lseek / read / write / close
- 子主题 2
文件描述符
-
概念
- pcb 中 fd_array[struct file] 的下标
-
文件流指针与文件描述符的管关系
- 文件流指针封装了文件描述符
-
重定向
-
改变数据流向(文件描述符不变,文件改变)
-
改变文件描述符下标所对应的文件描述信息
-
接口
- dup2 (oldfd,newfd) 复制
重定向 >> >
- dup2 (oldfd,newfd) 复制
-
-
缓冲区
- 通常说的缓冲区,指的是文件流指针描述的缓冲区;系统调用是没有这个缓冲区的这个缓冲区也被称为用户态缓冲区
库的生成与使用
库的生成
-
动态库
- gcc -fPIC -c main.c -o main.o
- gcc --share mian.o -o libmain.so
- 前缀 lib 后缀 .so
-
静态库
- gcc -c mian.c -o mian.o
- ar -cr libmain.a mian.o
- 后缀 .a
库的使用
-
程序编译时的链接
-
将库文件放在指定的路径下 :/lib/lib64
-
设置环境变量
- LIBRARY_PATH
-
-lmain,使用-L选项指定库路径
-
-
动态库 程序运行时的加载
-
将库文件放到指定路径下
-
改变环境变量
- LD_LIBRARY_PATH
-
文件系统
-
每个磁盘分区都有文件系统
-
文件类型
- d:文件夹
- -:普通文件
- l:软连接文件
- b:块设备文件
- p:管道文件
- c:字符设备文件
- s:套接口文件
-
10 位访问权限
- 1位文件类型 + 3位文件所有者权限 + 3位文件所属组权限 + 3位其他用户权限
-
组成
- 数据块区域
- inode 节点区域
- inode bitmap
- data bitmap
- 超级块
-
软连接 / 硬链接文件
-
软连接文件
- 独立的文件,功能类似于快捷方式
-
硬链接文件
- 一个文件的目录项
-
ln 硬链接 link 软连接
-
硬链接文件是一个文件别名,与原文件操作同一个 inode 节点
软连接是一个独立的文件
删除源文件,软链接文件失效,硬链接文件(inode计数 -1)
IPC
概念
- 操作系统为用户提供的进程间通信方式
为什么要给用户提供IPC
- 进程独立性
IPC为什么提供多种方式
- 不同应用场景
本质
- 一个公共的媒介
通信方式
管道
-
分类
-
命名管道
- 任意进程间通信
-
匿名管道
进程创建匿名管道,系统在内核创建一块缓冲区,操作系统返回两个文件描述符作为管道的操作句柄(一读一写)
- 只能用于具有血缘关系的进程间通信 – 子进程复制父进程文件描述符
-
-
本质
- 内核中一块缓冲区
-
操作
- 通过 io 接口实现管道这个缓冲区的操作
-
接口
-
int pipe( int pipefd[2] );
pipefd :至少具有两个 int 型元素的数组
创建一个管道,通过 pipefd 获取系统返回的管道操作句柄,其中:
pipefd[0] :只读
pipefd[1] :只写
返回值 0 失败 -1 -
特性
-
半双工通信 (可选向的单向通信)
-
读写特性
- 没有数据,read 阻塞 ,直到写入
数据满了,write 阻塞 ,直到数据被读走
若所有写端关闭,read 读完所有数据后 返回 0
若所有读端关闭,write 触发异常 ,进程退出
- 没有数据,read 阻塞 ,直到写入
-
命名管道文件的打开特性
- 若管道文件当前没有以写的方式打开,则以只读的方式打开时会阻塞
若管道文件当前没有以读的方式打开,则以只写的方式打开时会阻塞
- 若管道文件当前没有以写的方式打开,则以只读的方式打开时会阻塞
-
自带同步互斥
- 管道的读写数据大小在不超过PIPE_BUF(4096) 时保证操作的原子性 性
-
提供字节流服务
- (特性:传输灵活但是会产生粘包问题 多条当一条处理)
-
生命周期随进程
-
-
共享内存
-
本质
- 开辟一块物理内存,映射到各个进程的虚拟地址空间中
-
特性
- 最快
-
接口
1.在物理内存中申请一块空间
shmget
2.通过页表映射到虚拟地址空间
shmat
4.解除映射关系 (因为多个进程访问,不能直接删除)
shmdt
5.删除共享内存
shmctl- shmget …
消息队列
-
本质
- 内核当中的一个优先级队列
- 有类型的数据块传输
信号量
对资源进行访问操作之前,先判断信号量计数(是否有资源能够操作)
计数 <= 0 ;等待
计数 > 0 ;直接返回(直接操作)计数 -1
若有进程创建资源,计数 +1 ;并且唤醒等待队列上的进程
-
本质
- 内核中的一个计数器 - 资源计数
-
功能
-
实现进程间的同步与互斥
- 同步 时序合理性 { 等待 ,唤醒 }
互斥 唯一访问
- 同步 时序合理性 { 等待 ,唤醒 }
-
信号
概念
- 信号是一个软件中断,打断进程当前操作,去处理信号所表示的事件
- 前提 :必须能够识别
信号的种类
-
62种
-
可靠信号
- 34 ~ 64
-
非可靠信号
- 1 ~ 31
-
-
kill -l
信号的生命周期
-
产生
-
硬件
- CTRL + C 退出
CTRL + Z 中止
CTRL + | 退出
- CTRL + C 退出
-
软件
- kill -signum -p pid 向进程发送signum信号
kill (pid, signum) 向某进程发送信号
raise (signum) 给自己发送一个信号
abort (void) 使当前进程接收到信号而终止
alarm ( int ) 定时器
- kill -signum -p pid 向进程发送signum信号
-
-
注册
- 可靠信号 :在 pcb 中的未决信号集合中进行标记,并在sigqueue中添加节点
- 非可靠信号:是给sigqueue链表添加一个信号节点,并且将pending集合对应的位图置1,当这个信号注册的时候
如果位图已经置1,代表信号已经被注册过了,因此不做任何操作,不会添加新的信号节点
-
注销
- 可靠信号:删除一个节点,然后查看链表中还有没有相同信号的节点,如果还有,信号对应的位图组依然置1,如果没有相同的节点,代表这个信号已经全部被处理了,因此将对应的位图置0
- 非可靠信号:删除链表中的节点,并将对应的位图置0
-
处理
-
打断进程当前操作,去执行信号回调函数
-
处理方式
如何修改信号处理函数 :
sighandler_t signal (int signum,sighandler_t handler ) ;handler :用户传入的处理函数
信号会打断当前的阻塞操作-
默认
- SIG_DFL
-
忽略
- SIG_IGN
-
自定义
- 自定义默认处理函数
-
-
信号的阻塞
- 在pcb的信号阻塞位图中标记阻塞信号到来之后,暂不处理
- 阻塞信号集合 block
函数的重入与不可重入
-
重入概念
- 同步在多个执行流中进入同一函数执行
-
函数可重入与不可重入的关键点
- 这个函数是否对临界资源(全局数据)进行了非原子操作(不受保护的操作)
线程
线程概念
-
Linux下的线程是一个轻量级的pcb,同一进程中的线程共享进程中的大部分资源
-
线程是CPU调度的基本单位 /进程是资源分配的基本单位
-
线程的独有与共享
-
独有
- 栈 / 寄存器 / 信号屏蔽字 / errno / 线程ID
-
共享
- 虚拟地址空间 / 文件描述符表 / 信号处理方式 / 当前工作路径 / 用户ID.组ID
-
-
多进程与多线程任务处理优缺点
-
多进程
- 稳定性高
-
多线程
- 通信方便
- 创建 / 销毁成本低
- 调度成本低
- 缺乏访问控制,一些系统调用以及异常都会对整个进程造成影响
-
线程控制
-
线程创建
- pthread_create 参数:创建的线程id,线程参数,线程运行函数的起始地址,运行函数的参数
-
线程终止
- return
pthread_exit (void *retval)
pthread_cancel (pthread_t tid)
- return
-
线程等待
-
概念
- 等待线程退出,获取返回值,回收线程资源
-
接口
- pthread_join ( pthread )
-
前提
- 线程处于 joinable 状态
- 处于 joinable 的线程退出不会自动释放资源
-
-
线程分离
-
概念
- 设置线程属性为 detach
- 被分离的线程推出后自动回收资源
-
接口
- pthread_detach(pthread_t tid)
-
线程安全
-
概念
- 多个线程对临界资源进行性争抢访问,不会出现数据二义性
-
实现
-
同步
-
概念
- 时序合理性
-
实现
- 条件变量
- 信号量
- 等待与唤醒功能
-
-
互斥
-
概念
- 唯一性
-
实现
-
互斥锁
-
原理
- 计数器的原子判断
-
本质
- 只有0/1的原子操作计数器
-
死锁
-
概念
- 多个线程对多个锁资源进行争抢操作,顺序不当造成环路等待导致程序无法执行
-
必要条件
- 互斥
- 不可剥夺
- 请求与保持
- 环路等待
-
避免死锁
- 银行家算法 ,死锁检测算法
-
-
接口
-
定义互斥锁变量 pthread_mutex_t
-
初始化 pthread_mutex_init(&mutex,NULL)
-
加锁
- pthread_mutex_trylock (&mutex) 非阻塞
- pthread_mutex_lock (&mutex) 阻塞
-
解锁 pthread_mutex_unlock (&mutex)
-
销毁 pthread_mutex_destroy (&mutex)
-
-
-
条件变量
-
原理
- 线程在对临界资源访问之前,先判断是否能够操作;可以操作则直接操作;否则等待
-
本质
- 等待 + 唤醒 + 等待队列
-
接口
- 1.定义 pthread_cond_t cond
2.初始化 pthread_cond_init(&cont , NULL)
3.等待 pthread_cond_wait(&cont , &mutex)
4.唤醒 pthread_cond_signal (&cond)
5.销毁 pthread_cond_destroy(&cond)
- 1.定义 pthread_cond_t cond
-
注意
- 条件变量的判断应该是一个循环判断
- 线程什么时候等待需要一个判断条件,这个条件也是一个临界资源,因此对这个资源的操作就需要被保护(默认为互斥锁)
-
-
-
-
-
生产者与消费者模型
-
作用
- 解耦合
- 支持忙先不均
- 高并发
-
实现
- 一场所 两角色 三种关系
-
线程池
-
概念
- 多个线程 + 任务队列
-
作用
- 避免大量线程的创建 / 销毁成本
- 避免资源耗尽的危险
-
实现
线程安全的单例模式
-
设计模式
-
单例模式
-
实现
-
饿汉
-
懒汉
- 非线程安全
- 线程安全
- volatile
- 避免锁冲突二次判断
-