并发与并行

学习目标

通过本集的学习,你将能够:

  • 理解并发概念
  • 区分线程与进程
  • 掌握同步机制
  • 认识死锁问题

1. 并发 vs 并行

1.1 并发

并发是多个任务在宏观上同时进行,微观上交替执行。

并发示例:
时间 →
[任务1] [任务2] [任务1] [任务2] [任务1] [任务2]

1.2 并行

并行是多个任务在物理上同时执行(多核 CPU)。

并行示例:
CPU 1: [任务1] [任务1] [任务1]
CPU 2: [任务2] [任务2] [任务2]

2. 进程与线程

2.1 进程

进程是程序的执行实例,有独立的内存空间。

进程特点:
- 独立内存空间
- 开销大
- 安全隔离

2.2 线程

线程是进程内的执行单元,共享进程内存。

线程特点:
- 共享内存
- 开销小
- 通信方便
- 需要同步

3. 同步机制

3.1 互斥锁

互斥锁(Mutex):
lock()
临界区
unlock()

保证临界区同时只有一个线程执行

3.2 信号量

信号量(Semaphore):
控制同时访问资源的线程数量

4. 死锁

4.1 死锁条件

死锁四个必要条件:
1. 互斥:资源只能被一个线程持有
2. 持有并等待:持有资源同时等待其他资源
3. 不可剥夺:资源不能被强行夺走
4. 循环等待:形成等待环

5. 实用案例

5.1 案例:Python 多线程

import threading

def print_numbers():
    for i in range(10):
        print(i)

def print_letters():
    for c in 'abcdefghij':
        print(c)

t1 = threading.Thread(target=print_numbers)
t2 = threading.Thread(target=print_letters)
t1.start()
t2.start()
t1.join()
t2.join()

6. 自测问题

  1. 并发和并行的区别是什么?
  2. 进程和线程的区别是什么?
  3. 什么是互斥锁?
  4. 死锁的四个条件是什么?
  5. 如何避免死锁?

7. 下集预告

下一集我们将学习泛型与多态!

参考资料

  • 《程序设计语言:概念与构造》
« 上一篇 模块化与命名空间 下一篇 » 泛型与多态