网络编程和并发
进程、线程、协程
- 多线程和多进程是并发编程的两种实现方式。
区别:
特性 | 多线程 | 多进程 |
---|---|---|
执行单位 | 线程,运行在同一进程内,共享内存 | 进程,独立的内存空间 |
开销 | 创建开销小,切换成本低 | 创建开销大,切换成本高 |
GIL 影响 | 受 GIL 限制,多线程不能同时执行多个 Python 字节码 | 独立进程,不受 GIL 限制,可以并行执行 |
适用场景 | I/O 密集型任务,如文件读写、网络请求 | CPU 密集型任务,如数据计算 |
-
使用场景:
- 多线程:I/O 密集型任务(网络爬虫、文件读写)。
- 多进程:CPU 密集型任务(图像处理、大数据计算)。
协程与多线程、多进程的比较
3. 什么是协程?
协程是一种轻量级的线程,可以通过编程控制执行的挂起和恢复,适用于异步任务和并发场景。与线程相比,协程不需要系统资源的上下文切换,因此开销更小。
1.协程的特点
-
单线程并发:协程在单个线程中运行,通过手动切换实现并发。
-
非阻塞:协程可以在 I/O 操作时挂起,释放 CPU,等待数据可用时继续执行。
-
控制权切换:协程之间通过挂起 (
yield
或await
) 和恢复 (next
或return
) 来切换。使用 async/await 实现协程
从 Python 3.5 开始,
async
和await
引入协程的语法糖,简化了协程的定义和调用。示例:
import asyncio async def async_example(): print("Start coroutine") await asyncio.sleep(1) # 模拟异步操作 print("End coroutine") # 运行协程 asyncio.run(async_example())
协程与多线程、多进程的比较
特性 | 协程 | 多线程 | 多进程 |
---|---|---|---|
执行单位 | 单线程多协程 | 多线程 | 多进程 |
切换方式 | 程序员手动切换(await ) |
系统调度 | 系统调度 |
开销 | 低(用户态切换,无需锁) | 中(需要 GIL 的协调) | 高(需要进程间通信) |
适用场景 | I/O 密集型任务 | I/O 密集型任务 | CPU 密集型任务 |
并行性 | 无(伪并发) | 受 GIL 限制 | 支持多核并行 |
2、什么是 GIL
(全局解释器锁)?它对多线程有什么影响?
GIL(Global Interpreter Lock) 是 Python 的全局解释器锁,它确保同一时间只有一个线程执行 Python 字节码。
- 作用:
- 简化 CPython 的内存管理(尤其是垃圾回收)。
- 确保线程安全。
- 影响:
- 多线程受限:在多核 CPU 上,Python 的多线程不能实现真正的并行。
- 多进程无影响:不同进程有独立的 GIL。
- 如何规避 GIL 的影响:
- 使用多进程替代多线程。
- 在 C 扩展模块中释放 GIL。
- 使用不依赖 GIL 的第三方库(如 NumPy)。