在平时使用时,处理大量文件时单线程较慢,使用多线程可以加速处理速度。
本文以 统计图像shape,并写入csv 为例,了解python多线程操作
概要使用python调用多线程可以分为4步操作:
- 将需要多线程并行处理的操作定义为函数func
- 定义多线程对象,并确定线程数
- 将需要多线程操作的 可迭代对象 映射到 函数func中
- 返回多线程处理结果
多线程对象定义代码:
pool = multiprocessing.Pool(4) ... pool.close() pool.join()
其中,4表示线程数,pool表示多线程处理对象,为简化,建议使用以下形式:
with multiprocessing.Pool(4) as p:
...
多线程函数映射:
表示多线程处理对象pool有多个映射方法进行多线程处理,本文使用imap方法,其他方法可参考:
python多线程学习2——不同映射方法对比_DL_GIS-CSDN博客
或
【Python】Python进程池multiprocessing.Pool八个函数对比:apply、apply_async、map、map_async、imap、starmap..._随波一落叶-CSDN博客_starmap_async
代码示例:
以 统计图像shape,并写入csv 为例
分别展示普通遍历(单线程)、无效多线程(多线程并未进行实际操作)、imap多线程(多线程读取图像并返回 图像名、图像shape,单线程将返回值写入csv,后续会对该过程进行进一步优化)
import os
import time
import cv2
import pandas as pd
from multiprocessing import Pool
from tqdm import *
def _func(file_path):
'''
需要多线程进行的任务功能
:param file_name:
:return:
'''
img = cv2.imread(file_path)
file_name = os.path.basename(file_path)
return img.shape,file_name
def _func0(input):
return input
def mlt_compare1():
t1 = time.time()
df1 = pd.Dataframe(None, columns=['file_name', 'shape'])
img_dir = r'E:1_datasetOtherDataimagecaption_aichallengerai_challenger_caption_validation_20170910ai_challenger_caption_validation_20170910caption_validation_images_20170910'
with tqdm(os.listdir(img_dir)[:1000]) as pbar:
for file_name in pbar:
img = cv2.imread(os.path.join(img_dir, file_name))
df1.loc[len(df1)] = [file_name, img.shape]
print(df1)
t2 = time.time()
# 由于_func0仅对遍历的list进行读取,实际上多线程并未执行任何操作
# 由于调用了多线程相关任务,因此时间反而增加
t3 = time.time()
df2 = pd.Dataframe(None, columns=['file_name', 'shape'])
with Pool(4) as p:
with tqdm(os.listdir(img_dir)[:1000]) as pbar:
mpbar = p.imap(_func0, pbar)
for file_name in mpbar:
img = cv2.imread(os.path.join(img_dir, file_name))
df2.loc[len(df2)] = [file_name, img.shape]
print(df2)
t4 = time.time()
# 为保证多线程其作用,在_func中定义数据读取功能,并返回所需要的结果
# imap返回顺序结果
t11 = time.time()
df10 = pd.Dataframe(None, columns=['file_name', 'shape'])
with Pool(4) as p:
files_list = [os.path.join(img_dir,file_name) for file_name in os.listdir(img_dir)[:1000]]
with tqdm(files_list) as pbar:
mpbar = p.imap(_func, pbar)
for img_shape, file_name in mpbar:
df10.loc[len(df10)] = [file_name, img_shape]
print(df10)
t12 = time.time()
print('单线程用时',t2-t1)
print('无效多线程用时',t4-t3)
print('有效多线程用时',t12-t11)
if __name__ == '__main__':
mlt_compare1()



