程序员的自我修养阅读笔记
操作系统简单介绍
多个进程抢占系统资源,根据重要程度不断在多个进程间切换
一个进程中有多个线程,共享代码/数据/内存/已开文件等资源,但有各自的局部寄存器和栈,通过并发执行提高效率.
并发的实现:多核同时运行;线程调度(抢占)
调度:轮转法,优先级调度
Linux 的多线程
fork+exec创造新进程,内存空间写时复制COW,且新fork的pid返回0,老任务返回原pid,可以用ifelse调度这两种情况的任务.且只有exec可以执行新映像.
clone创造新线程,共享内存,是一对一线程
原子化
原子指令
同步与锁 :二元信号量,互斥量(临界区),读写锁,条件变量
因为进程内的寄存器导致不能同步数据,或者因为动态调度调整指令顺序.volatile,
gcc编译过程
预处理 gcc -E hello.c -o hello.i
编译gcc -S hello.i -o hello.s
汇编gcc -c hello.s -o hello.o
链接
编译器
扫描,语法分析(语法树),语义分析(静态语义动态语义),源代码优化(中间代码(三地址码/P-代码)),代码生成(架构不同),目标代码优化(CPU复杂,编译器指令生成复杂,gcc很牛逼).
链接器
重定位:修改程序后,所有绝对地址的重新计算,很麻烦
模块化后需要链接
对象文件包括:机器代码,符号表,重定位信息,(调试信息)
链接:符号决议,地址和空间分配,重定位
目标文件里有什么
节/段
机器指令:代码段 ‘.code’ ‘.text’
全局变量静态变量’.data’ ‘.rodata’ ‘.bss’
重定位表 ‘.rel.data’’.rel.text’里面有每一个重定位入口.里面本来都是假地址0或者-4的,要重新计算
符号表
分析这个ELF文件
文件头(包括一个段表:,描述各个段在文件中偏移位置和属性的数组)
代码段
数据段
未初始化的数据段
链接
重定向,绝对寻址修正,相对寻址修正
动态链接
把程序按模块拆成独立部分,运行时再重定位和链接,而不是把所有目标文件链接成一个可执行文件.不同程序间有共享文件模块.
节省空间,方便单个程序更新,每次构建时链接耗时少
共享文件地址在哪:
C++特殊:重复代码消除,全局构造析构,特性导致二进制兼容问题
模板实例化后放在同一个代码段里
虚函数,外部内联函数,默认拷贝构造函数,赋值操作符,都是一堆文件里只生成一个代码段,相同就删去
全局构造’.init’
全局析构’.fint’
二进制兼容
ABI
自己写一个不需要调用库的静态链接程序