OS-并发-从入门到放弃

放弃

进入并发领域,我们将要放弃很多默认的条件:

  1. 原子性
    "程序独占处理器执行"的假设不再成立。程序可能在运行中被打断,甚至一条汇编指令也可能被中断。例如,更新共享变量时可能因中断导致数据不完整。为解决此问题,需通过同步原语(如锁)将操作封装为临界区,确保原子性。
  2. 顺序性
    编译器将代码视为单线程优化,可能导致多线程中变量未被实际访问。例如,若同步变量因编译器重排而未被及时刷新,将引发竞态条件(race condition)。这要求开发者显式使用内存屏障或原子操作保证可见性。
  3. 可见性
    现代处理器通过指令重排和缓存优化提升性能,但可能导致线程间数据不一致。例如,线程A的写入可能因缓存未同步而对线程B不可见。需通过硬件支持(如CPU内存模型)和操作系统机制(如缓存行冲洗)保证可见性。

并发 vs 并行

OS-交换空间与缓存管理

交换空间

现代操作系统通过交换空间(swap space)实现虚拟内存的扩展能力。当物理内存容量不足以容纳所有活跃进程的页时,操作系统会将低频访问的页换出(page out)到磁盘的专用交换区域,从而释放物理内存资源。这种机制使得程序能够使用远大于实际物理内存的地址空间。

OS-分页与页表

快速地址转换(TLB)

在《OS-内存管理》中指出,分页机制的一个主要缺点是可能导致额外的内存访问开销。为了加速虚拟地址到物理地址的映射过程,避免频繁查询页表,计算机系统采用了常见的加速技术——缓存。

OS-内存管理

空闲空间管理

当内存总被划分为固定大小的块时,内存的管理比较容易。但如果需要将内存划分为可变长度的块,比如malloc和free、操作系统的分段操作,会出现我们熟悉的内存碎片问题。

OS-访问系统对象

lseek

之前在地址空间一文中提及 mmap 可以映射文件到内存地址空间,并通过指针实现随机访问。对于使用 read/write 的情形,系统调用 lseek 同样可以达成这个目的。