使用传统的threading的Thread进行操作
import threading
th_list = []
th_list.append(threading.Thread(target=self.compare_compute_similar, args=(xxxx, )))
for th in th_list:
th.start()
for th in th_list:
th.join()
执行的效果如图所示
使用threadpool 采用线程池的方式进行操作
import threadpool
data_list = bwm.get_picture_from_target_single()
pool = threadpool.ThreadPool(100)
requests = threadpool.makeRequests(bwm.compare_compute_similar, data_list)
[pool.putRequest(req) for req in requests]
pool.wait()
注意在这个地方我们需要提前构建一个数据列表
使用mutliprocess.Pool 采用进程池的方式进行操作
from multiprocessing import Pool
data_list = bwm.get_picture_from_target_single()
pool = Pool(4)
pool.map(bwm.compare_compute_similar,data_list)
pool.close()
pool.join()
在这里我们使用4个进程完成了此次的实验,时间大概压缩到了多线程的1/4
我们来分析下,是因为我们有100条数据,每条数据运行时间2s,总体的运行时间200s,所有的时间都在进行计算操作,线程是在时间片完成时或在IO操作、网络请求时,会进行切换,所以在所有的操作都是计算的时候,每个线程都是满时间片进行切换的,也就是说,计算是多少时间,多线程就是多少时间,在这点上,多线程并没有节约时间,反观多进程,使用map的方式将数据分成进程数量,每个进程拿到的都是1/4的数据,所以每一个的执行时间都是总数量的1/4,4进程并行,最终所用时间是多线程的1/4.
附加知识点
在多进程的条件下,我们能不能开启和电脑总核数一样的进程? 不能
分析如下: 在进程运行的时候分为两个内存类型:实际使用内存、进程占用内存。
4个python进程的实际内存都是1G左右,但是进程占用内存是2G左右,我们看到的实际使用内存是9G,但是实际上我们内存已经有一部分预定出去了,这个部分的内存不显示,但是并不能用,我们的电脑有16个核的时候,可以使用cpu_count(),方法得到,我们开启全部的进程,占用内存达到了32G以上,远超我们本机系统的16G,所以一直报告memoryerror的问题,适当的调节调用得核个数即可。
我们还可以将进程和线程进行结合:
def compare_compute_similar(xxxx):
pass
def multiprocessing_deal_with_data(data_list):
pool = threadpool.ThreadPool(30)
requests = threadpool.makeRequests(self.compare_compute_similar, data_list)
[pool.putRequest(req) for req in requests]
pool.wait()
# 注意这个地方:我们要将我们的数据构造成[[xxx...],[xxx...],[xxx...]]
data_list = bwm.get_picture_from_target_single()
cores = 4
data_split = np.array_split(data_list,cores)
new_data_split = [data.tolist() for data in data_split]
pool = Pool(4)
pool.map(bwm.multiprocessing_deal_with_data,new_data_split)
pool.close()
pool.join()
我们看到这个时间是要比我们的单用多进程是要慢的,是因为除了计算的所有时间之外,系统还要维护线程的切换,耗费大量的时间。所以实际上全计算的我们适合使用多进程,存在IO和网络请求的可以加上多线程。