问题背景: 前段时间在做一个几十万文本数据处理的工作,需求是这样的:读取文本数据,对于每一条文本数据要调用两个接口,分别得到结果后做一个后处理并存入文件中。该需求做起来可以说是非常简单了,但我遇到的问题是效率问题,几十万的文本数据进行简单处理需要几个小时,时间的花费远远超出了我的预期。因此总结了这个Python中多进程和多线程的相关分享。
1. 问题剖析
1.1 问题分析
上述问题的数据流为:读取文件->对每行数据调用两个接口->得到结果并做后处理->写入文件。
上述问题的特点:
- 数据量大,且在同一个文件
- 处理后的数据需要写在同一个文件里
- 两个接口之间没有交互,但是对于每一条数据的后处理,需要得到两个接口返回的结果后进行
目前,该问题针对每一条数据的耗时现状:
1.2 解决方案分析
针对上述问题的分析,为了引入Python的多线程和多进程的处理思路,该问题可以有以下提速方案:
- 大量的文本数据,可以将数据分块读取,用不同的线程/进程来处理数据,该方案面临多线程/进程读写文件的问题
- 由于两个接口是相互独立的,他们之间没有交互,因此可以采用多线程/进程的思路来做并行化
经过上述分析,我们应该用多线程还是多进程的思路呢?我们该对哪一部分的处理进程并行化呢?接下来做具体分析。
注:有线程/进程基础的同学,可直接跳过2.1节
2. 相关基础及问题解决过程
2.1 相关基础
线程与进程
众所周知,计算机中的计算任务都是CPU(不考虑GPU)提供的,操作系统是计算机的大管家,它控制着CPU对哪个任务进行计算、计算多长时间,这被称为资源分配。对于古老的单核(一个CPU)计算机来讲,它要承担所有的计算任务,但这些任务又不能同时执行,这时CPU的工作是分时间片的,以串行的方式,分别对不同的任务进行计算,由于其计算的速度很快,因此用户端感受不到它频繁的在不同人物之间切换。直到多核计算机的出现,一台计算机有多个CPU,可以满足多个任务同时计算,大大提升效率。因此,多线程和多进程的概念也被提出。
- 线程:线程也叫做轻量级进程,是程序执行的最小单位。
- 进程:进程是计算机程序一次执行的实例,是计算机资源分配和调度的基本单位,一个进程至少包含一个线程。
线程是属于进程的,线程运行在它所属的进程空间中,一旦它所属的进程退出运行,那该进程下的线程也将会被强制结束并清除,同属于一个进程的所有线程共享该进程拥有的资源,线程间也可以直接通信。
串行和并行
和我们的认知相同,一个或多个任务由多个生产线同时进行来完成,花费的总时间肯定是比单条生产线依次完成一个或多个任务花费的总时间要短,前者就是我们所说的并行的方式,后者则是串行的方式。对于单核计算机来说,是无法实现真正意义上的并行的,因为CPU是不能对多个任务同时进行处理的,真正的并行运行是在多核CPU上实现的ÿ