一键阐述“多线程、多进程、多任务”的场景需求
“三多”指的是什么,具体什么意思?
- 多任务(操作系统层面):公司同时做多个项目
- 多进程(程序层面):公司有多个独立部门
- 多线程(模块/任务层面):部门里多个员工协同工作
这样来看,不仅明白了意思,还知悉了所在维度
如何选择多进程和多线程:
- CPU 密集型任务:
- 如果任务主要涉及大量的计算,如图像处理、科学计算、加密解密等,那么应该选择多进程。
- 多进程可以充分利用多核 CPU 的并行计算能力,提高程序的整体性能。
- 因为python存在GIL锁,所以多线程在cpu密集型任务中,不能充分利用多核cpu的优势。
- I/O 密集型任务:
- 如果任务主要涉及大量的输入/输出操作,如网络请求、文件读写、数据库访问等,那么可以选择多线程。
- 多线程在等待 I/O 操作完成时,可以切换到其他线程执行,提高程序的并发性。
- 多线程在IO等待的时候,会释放GIL锁,让其他线程运行。
- 需要隔离性的任务:
- 如果任务之间需要高度的隔离性,避免相互干扰,那么应该选择多进程。
- 每个进程都有独立的内存空间,一个进程的崩溃不会影响其他进程。
- 需要频繁创建和销毁的任务:
- 如果任务的创建和销毁频率很高,那么应该选择多线程。
- 线程的创建和销毁开销较小,适合执行频繁的子任务。
- 需要共享数据的任务:
- 如果任务之间需要频繁地共享数据,那么可以选择多线程。
- 线程共享进程的内存空间,数据共享更加方便
已知”进程是操作系统中资源分配的基本单位“,对于多进程和多线程来说为什么不直接选用多进程?
- 资源开销:
- 进程的创建、销毁和切换开销较大,占用更多的系统资源(内存、CPU)。
- 如果创建过多的进程,可能会导致系统资源耗尽。
- 通信成本:
- 进程之间的通信需要使用特定的机制(如管道、消息队列),相对复杂且开销较大。
- 线程之间共享内存,通信更加方便快捷。
- 复杂性:
- 多进程编程需要考虑进程间的同步和通信问题,增加了程序的复杂性。
- 多线程编程虽然也需要考虑线程安全问题,但在某些情况下相对简单
(线程安全问题主要是代码层面的问题,需要程序员在编写代码时进行处理)
模拟场景:文件处理系统
1. 多任务(操作系统层面)
[OS] 操作系统
[Task1] 文件监控程序
[Task2] 文件解析程序
[Task3] 数据处理程序
[Task4] 结果输出程序
[OS] 快速切换 [Task1]、[Task2]、[Task3]、[Task4]
2. 多进程(程序层面)
[Process1] 文件监控程序
监控文件目录
发送文件信息到 [Process2]
[Process2] 文件解析程序
[SubProcess2.1] 文本解析进程
[SubProcess2.2] 图像解析进程
接收文件信息
启动相应的解析进程
[Process3] 数据处理程序
接收解析后的数据
进行数据计算
[Process4] 结果输出程序
接收处理结果
输出结果到数据库/报告
3. 多线程(模块/任务层面)
在 [SubProcess2.1] 文本解析进程内:
[Thread1] 读取文件线程
[Thread2] 解析文本内容线程
[Thread1] -> [Thread2] (数据传递)
在 [Process3] 数据处理程序内:
[Thread3] 子任务1线程
[Thread4] 子任务2线程
[Thread3] & [Thread4] (并发执行)
流程描述:
文件监控:
[Process1] 监控文件目录,发现新文件。
[Process1] 将文件信息发送给 [Process2]。
文件解析:
[Process2] 接收文件信息,判断文件类型。
如果文件是文本:
启动 [SubProcess2.1]。
[Thread1] 读取文件,[Thread2] 解析文本。
如果文件是图像:
启动 [SubProcess2.2]。
(图像解析线程类似)
数据处理:
[Process3] 接收解析后的数据。
[Thread3] 和 [Thread4] 并发执行数据计算。
结果输出:
[Process4] 接收处理结果。
输出结果
关键点:
[OS]:操作系统,负责多任务调度。
[Process]:进程,独立的程序模块。
[SubProcess]:子进程,进程内的独立模块。
[Thread]:线程,进程内的执行单元。
->:数据流动。
&:并发执行。