背景:
想输入一个list,经过函数filter_noresult,判断该list中哪些数据是有结果哪些数据没结果,返回两个list。
单进程执行的话,40w数据需要执行2小时。后来开了4个进程之后40w数据执行半小时就行。
使用的是:from multiprocessing import Pool
使用的是异步执行操作:pool.apply_async。
主要用的是很简单的想法,先将40万的数据切割成4份,然后每一份同时异步执行,最后再把结果合并起来。代码如下所示:
执行异步操作的代码如下所示:
origin_len = len(origin_line)
t=4
#先把数据分成4份
for i in range(t):
origin_keyword_list.append(origin_line[round(origin_len*i/t):round(origin_len*(i+1)/t)])
# 开启4个进程
pool = Pool(t)
print("length of origin_keyword_list :",len(origin_keyword_list))
res_list = []
# 执行异步操作,并将异步操作的数据结果存储起来
for part in range(len(origin_keyword_list)):
#!!!!异步执行操作,
res = pool.apply_async(func=filter_noresult,args=(origin_keyword_list[part],))
res_list.append(res)
#res_filted_list.append(res_filted)
在上面执行异步操作的时候,在坑里呆了很久,主要的错误是在:
res = pool.apply_async(func=filter_noresult,args=(origin_keyword_list[part],))
这句,当初在写的时候没有写",",就是在传递参数的时候少写了一个逗号,是这样写的:
res = pool.apply_async(func=filter_noresult,args=(origin_keyword_list[part]))
然后在获取结果数据的时候就一直的报错。
因为之前在为函数传两个参数的时候是这样写的:
result.append(pool.apply_async(word_filter, (i,black_list)))
是能够正确执行的,但是只传一个参数的时候就一定要多加一个“,”
在获得数据之后一下步就解析数据了,由于是在进程池中建立了4个进程,而每个进行返回2个list,所以结果res中数据的存储为:
res_list---<class 'list'>
|----------ApplyResult
|----------good_keyword---<class 'list'>
|----------filted_keyword---<class 'list'>
|----------ApplyResult
|----------good_keyword---<class 'list'>
|----------filted_keyword---<class 'list'>
|----------ApplyResult
|----------good_keyword---<class 'list'>
|----------filted_keyword---<class 'list'>
|----------ApplyResult
|----------good_keyword---<class 'list'>
|----------filted_keyword---<class 'list'>
返回的时候会返回8片数据,数据是有序的,因此在奇数的都是good_keyword_list的part部分,偶数的都是filted_keyword_list的part部分。
那么在合并数据的代码为:
flag_num = 0
for res_part in res_list:
for line in res_part.get():
#print(type(line))
flag_num += 1
#print(type(line))
#print(len(line))
for i in line:
if flag_num % 2 == 1:
good_keyword_all_list.append(i)
else:
filted_keyword_all_list.append(i)