一、概念
进程:进程是系统进行资源分配和调度的一个独立单位,一个任务就是一个进程(Process)
线程:线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。一个进程至少有一个线程(thread)。
二、任务:计算密集型 vs. IO密集型
1.计算密集型任务的特点是要进行大量的计算,消耗CPU资源,比如计算圆周率、对视频进行高清解码等等,全靠CPU的运算能力。这种计算密集型任务虽然也可以用多任务完成,但是任务越多,花在任务切换的时间就越多,CPU执行任务的效率就越低,所以,要最高效地利用CPU,计算密集型任务同时进行的数量应当等于CPU的核心数。
计算密集型任务由于主要消耗CPU资源,因此,代码运行效率至关重要。Python这样的脚本语言运行效率很低,完全不适合计算密集型任务。对于计算密集型任务,最好用C语言编写。
2.第二种任务的类型是IO密集型,涉及到网络、磁盘IO的任务都是IO密集型任务,这类任务的特点是CPU消耗很少,任务的大部分时间都在等待IO操作完成(因为IO的速度远远低于CPU和内存的速度)。对于IO密集型任务,任务越多,CPU效率越高,但也有一个限度。常见的大部分任务都是IO密集型任务,比如Web应用。
IO密集型任务执行期间,99%的时间都花在IO上,花在CPU上的时间很少,因此,用运行速度极快的C语言替换用Python这样运行速度极低的脚本语言,完全无法提升运行效率。对于IO密集型任务,最合适的语言就是开发效率最高(代码量最少)的语言,脚本语言是首选,C语言最差。
三、进程池和线程池
Pool可以提供指定数量的进程供用户调用,当有新的请求提交到pool中时,如果池还没有满,那么就会创建一个新的进程用来执行该请求;但如果池中的进程数已经达到规定最大值,那么该请求就会等待,直到池中有进程结束,才会创建新的进程来它。
import os
import sys
from functools import partial
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
worker_num = 10 #对于进程要看cpu的核
#定义任务,one_item 可迭代对象的迭代元素,static_parameter 静态参数,执行批量任务时不变的量,注意变量的位置,可变参数在不变参数之前
def task(one_item,static_parameter):
#定义工作流程
print(one_item)
return True
#线程池执行
def run_threadPool(all_items:list,static_parameter):
with ThreadPoolExecutor(max_workers=worker_num) as executor:
# 使用partial构造一个带默认参数的函数,给不变量进行赋值
results = executor.map(partial(task,static_parameter=static_parameter),all_items)
return results
#进程池执行
def run_processPool(all_items:list,static_parameter):
with ProcessPoolExecutor(max_workers=worker_num) as executor:
results = list(executor.map(partial(task,static_parameter=static_parameter),all_items))
return results
if __name__=='__main__':
run_threadPool(['1','2','3'],True)