一 多线程编程¶
多线程编程--锁¶
- 锁的类型(明确优劣):互斥锁,读写锁,自旋锁,递归锁,信号量,条件变量。
- 锁的分类:乐观锁与悲观锁(版本号,CAS检测),公平锁与非公平锁(插队)、可重入锁(统一线程多次)与不可重入锁
- 临界区:共享资源。特性:互斥访问,关联邻接资源,有限时间停留。
- 管理原则:互斥性,有限等待,非阻塞性,独立性。
- 实现机制:互斥锁,信号量,条件变量。原子操作(如CAS)与无锁编程。
- 原子操作与无锁编程:高频短任务。
多线程场景¶
- 两个线程交替打印1到10。
- 普通的int实现引用计数、线程安全吗?
地平线哦啊吗¶
二 操作系统¶
Windows/Linux 内存管理机制¶
- 区别?
虚拟内存¶
页面置换算法¶
进程、线程切换¶
调度信息:调度队列位置更新,时间片计数器重置、重分配。 内核态资源: - 线程上下文:寄存器(如pc),TLS,TCB状态,栈。 - 进程上下文:虚拟地址空间与页表,文件描述符表,进程全局资源(如全局变量),信号处理表,进程控制块(PCB/task_struct)的部分信息(如进程优先级、资源限制、父子进程关系)。 线程共享了进程的什么资源?
进程通信¶
¶
System V POSIX V
管道¶
pipe fifo
文件¶
文件想要读到cpu的步骤?
一.程序编译全过程¶
预处理、编译、汇编、链接
预处理¶
文件引用,宏定义、条件编译
编译过程¶
将文件编译成汇编代码文件(ASCLL文件,即.s)
汇编过程¶
通过不同平台汇编器将汇编代码翻译成机器码,生成二进制可重定向文件(.o) 同时产生==符号表==,没有被分配地址,必须经过链接
⭐⭐链接过程(动态链接原理)¶
- 首先将多个.o 文件相应的段进行合并,建立映射关系并且去==合并符号表==。分配虚拟地址。
- 动态链接原理?
- 地址无关代码:PIC,通过PC程序计数器偏移量重定位。
- GOT全局偏移表,间接寻址:为什么需要?代码段需要加载共享库,但是不能修改。所以变成访问全局静态区的GOT表,GOT表间接跳转或访问数据。
- 延迟绑定机制:过程链接表(首次绑定真实地址,后续直接跳转,减少重复开销)
- 过程:装载阶段->符号解析->重定位
细说符号表¶
符号¶
底层结构体大致分布: 地址偏移量+目标字节数+符号类型(数据、函数、源文件、节等)和绑定属性(全局符号、局部符号、弱符号)+其他情况
强、弱符号概念¶
强符号:函数名和已初始化的全局变量名 弱符号:未初始化的全局变量名。(extern,static) 强符号不能被多次定义,弱符号任选其一
表¶
- 存储全局、静态变量和函数的名称和类型的哈希表 典型绑定属性:
- T:代码区
- B:bss段
- D:已初始化数据区
- R:只读数据区 链接的时候:链接器回去符号表查找引用的符号是否存在 常量:编译期回去符号表查找const的值直接替换。 局部变量:不存到符号表。
静态链接¶
静态链接就是在链接阶段把.o文件中所依赖的静态库链接到一起,最终生成的可执行文件。文件大但是快
动态链接¶
静态链接缺点:所有可执行程序对同一段代码都有一份拷贝。如果都有printf,那就会存多份。
实现方法:当链接器发现某个符号的定义在DLL中,那么它不会把这个符号的定义加入到最终生成的可执行文件中,而是将该符号与其对应的库名称记录下来(保存在可执行文件中)。当要执行所调用DLL中的函数时,根据链接产生的重定位信息,系统才转去执行DLL中相应的函数代码。
更省空间,但也会带来执行速度慢和DLL地狱的问题(版本兼容、多库同用)
二.系统调用¶
1.进程控制¶
fork() execve() exit()/ _ exit wait()/ waitpid
2.设备管理¶
mmap();
2.内存管理¶
动态内存管理的底层工具,==malloc==的实现基础: - brk(地址+增量)/sbrk(直接增量,0为当前地址,可以返回旧地址) -
4. 网络通信¶
socket的所有结构
计网¶
一 TCP和UDP¶
- TCP场景:长连接(短连接https实际上也是TCP),可靠性保证有序无误,建立连接和重传不适合实时性强的场景。
- UDP场景:实时性高,高频小数据,广播多播,误差丢包概率大
情景¶
- A和B同时发包?TCP的全双工通信
- MOBA游戏需要什么样的传输协议?
二 大端和小端¶
- 是什么?为什么要用?如何用C++判断大端小端?