基本概念
进程=进程上下文(处理器上下文+内核上下文)+虚存 进程=线程+代码段+数据段+内核上下文
一个进程可以关联多个线程
- 每个线程有自己的处理器上下文
- 共享代码段、数据段和内核上下文
- 有自己的线程编号
线程 vs 进程
相同点:
- 都有自己的控制流
- 都能并发运行
- 都有上下文切换 不同点:
- 线程共享代码和数据,而进程通常不会
- 线程的资源开销比进程小
- 与进程相关的线程组成一个线程池,而父子进程间形成树状结构
线程 vs 协程
- 线程由 OS 管理,协程由程序本身管理
- 协程的资源开销比线程小
- 在多核 CPU 上,线程可以实现并行,而协程本身不实现并行
使用线程的优点:
- 易于在线程间共享数据
- 比进程更有效率 缺点:共享容易出错
共享
- 线程的内存模型是什么?
- 变量实例是如何映射到内存的?
- 有多少线程引用这些实例? 一个变量是共享的,当且仅当有多个线程引用这个实例。
线程内存模型
每个线程有独立的线程上下文,所有线程共享其余进程资源。
- 寄存器总是严格隔离并受到保护的,但虚存不是
- 任何线程可以读写其他任何线程的栈
将变量实例映射到内存
- 全局变量:虚存中只包含一个实例
- 局部变量:每个线程栈中包含一个实例
- 局部静态变量:虚存中只包含一个实例
互斥
任何顺序一致的交错执行都是可能的。
进度图: 个线程的执行模型化为一条 维直角坐标系中的轨迹,每条轴对应一个线程中指令的执行顺序,每个点对应一个可能状态。
临界区:临界区中的指令(读写共享变量)不应该交错
两个临界区的交集形成的空间区域称为不安全区。
若轨迹没有进入不安全区,则它是安全的

信号量
信号量 是具有非负整数值的全局变量,只能由两类操作处理:
- :如果 是非零的,则将 减一并返回,否则挂起这个线程
- :将 加一,如果有线程阻塞在 ,则选取其中一个重启
int sem_init(sem_t *sem, 0, unsigned int value);
int sem_wait(sem_t *s); // P
int sem_post(sem_t *s); // V用信号量实现互斥
每个共享变量与一个信号量 (初始为 1)联系起来,用 和 将相应的临界区包围起来。
用信号量调度共享资源
生产者&消费者:生产者等待空闲的 buffer,消费者等待 item
死锁
如何避免?
- 不同线程以相同顺序获得锁