笔记:关于链接库那点事儿
2021年7月31日
根据《程序员的自我修养-链接、装载与库(潘爱民著)》整理
1)总线。
北桥:高速设备(内存,缓存,CPU,PCIbridge)。南桥:低速设备(磁盘,USB,键盘,鼠标)。
2)内存。
增加中间曾层,内存映射,地址隔离,分段,分页。
3)线程。
程序执行最小单元:线程ID,指令指针,寄存器集合,堆栈。
线程三种状态:运行,就绪,等待
Linux Task:
-
fork:复制当前进程,只产生本任务的镜像
-
exec:使用新的可执行镜像覆盖当前的镜像
-
clone:创建子进程并从指定位置开始执行(产生新线程)
if ((pid=fork()) == 0) { // 子进程 } else { // 主进程 }
4)线程同步
信号量(任意线程获取和释放)
互斥锁(谁拥有谁释放)
临界区(进程内同步代码块)
条件变量(唤醒等待的线程)
5)线程过度优化
a. 阻止编译器为了提高速度缓存变量到寄存器:volatile x;
b. 阻止编译器调整操作 volatile 变量的指令次序 (volatile 无法阻止CPU动态调整执行顺序)
x = 0;
Thread1 Thread2
lock(); lock();
x++; x++;
unlock(); unlock();
CPU 乱序执行的问题:volatile 无法阻止CPU动态调整执行顺序:
x = y = 0;
Thread1 Thread2
r1 = y; y = 1;
x = 1; r2 = x;
采用 barrier() 指令 (lwsync),阻止 CPU 将 barrier 之前的指令交换到 barrier 之后。
6)多线程内部情况
用户线程:内核线程
- 1:1
CreateThread
clone(thread_fun, thread_stack, CLONE_VM, 0);
默认模型。真并发。数量限制,开销大 - N:1 线程切换快,无限的线程数量。性能提高不显著。
- M:N
7)编译和链接
a.预编译(展开全部的宏,处理全部预编译指令,删除注释):$ gcc -E
hello.c -o hello.i
b. 编译(cc 语法分析,构建,生成汇编代码):
$ gcc -S hello.i -o hello.S
直接:
$ gcc -S hello.c -o hello.S
c. 汇编(as 汇编代码转为机器指令产生目标文件):
$ as hello.S -o hello.o
直接:
$ gcc