1. 核心概念:线程与进程的区别
理解线程的第一步是搞清楚它和进程的关系:
- 进程是"工厂":它是资源分配的单位,拥有独立的内存空间、文件句柄等资源。
- 线程是"工人":它是CPU调度的单位,同一个进程内的线程共享进程的资源(内存、文件),但每个线程有自己的私有背包(寄存器、栈)。
关键点: 线程之间通信非常方便(直接读写共享内存),但也因此带来了风险,需要处理同步问题。
2. 线程的生命周期与调度
操作系统通过调度器来决定哪个线程占用CPU。线程通常经历以下状态:
- 新建:线程被创建。
- 就绪:等待CPU调度。
- 运行:正在执行代码。
- 阻塞:等待I/O或锁释放。
- 死亡:任务结束。
调度策略(如时间片轮转、优先级调度)决定了系统的并发效率。理解这一点有助于编写高并发程序。
3. 编程中的核心挑战:同步与互斥
这是多线程编程最难的部分,也是面试和实战的重灾区。
- 竞态条件 :多个线程同时修改同一个变量,导致结果不可预测。
- 例子: 两个线程同时执行
count++,最终结果可能少1。
- 例子: 两个线程同时执行
- 临界区:访问共享资源的代码段,必须保证一次只有一个线程进入。
- 锁机制 :
- 互斥锁:最基础的锁,保证临界区的互斥访问。
- 读写锁:允许多读单写,适合读多写少的场景。
- 自旋锁:线程在获取锁失败时循环等待,不释放CPU,适用于锁持有时间极短的场景。
- 死锁 :两个线程互相等待对方持有的锁,导致永久阻塞。
- *产生条件:* 互斥、占有并等待、不可抢占、循环等待。
- *解决策略:* 银行家算法、按顺序加锁、设置超时时间。