python中调用多进程加速处理文件
問題背景是這樣的,我有一批需要處理的文件,對于每一個文件,都需要調用同一個函數進行處理,相當耗時
有沒有加速的辦法呢?當然有啦,比如說你將這些文件分成若干批,每一個批次都調用自己寫的python腳本進行處理,這樣同時運行若干個python程序也可以進行加速
但是,有沒有更簡單的方法呢?比如說,我一個運行的一個程序里面,同時分為多個線程,然后進行處理?
實際上是有的
大概思路是這樣,將這些個文件路徑的list,分成若干個,至于分成多少,要看自己cpu核心有多少,比如你的cpu有32核的,理論上就可以加速32倍
直接上代碼:
復制代碼
# -*-coding:utf-8-*- import numpy as np from glob import glob import math import os import torch from tqdm import tqdm import multiprocessinglabel_path = '/home/ying/data/shiyongjie/distortion_datasets/new_distortion_dataset/train/label.txt' file_path = '/home/ying/data/shiyongjie/distortion_datasets/new_distortion_dataset/train/distortion_image' save_path = '/home/ying/data/shiyongjie/distortion_datasets/new_distortion_dataset/train/flow_field'r_d_max = 128 image_index = 0 txt_file = open(label_path) file_list = txt_file.readlines() txt_file.close() file_label = {} for i in file_list:i = i.split()file_label[i[0]] = i[1]r_d_max = 128 eps = 1e-32 H = 256 W = 256def generate_flow_field(image_list):for image_file_path in ((image_list)):pixel_flow = np.zeros(shape=tuple([256, 256, 2])) # 按照pytorch中的grid來寫image_file_name = os.path.basename(image_file_path)# print(image_file_name)k = float(file_label[image_file_name])*(-1)*1e-7# print(k)r_u_max = r_d_max/(1+k*r_d_max**2) # 計算出畸變校正之后的對角線的理論長度scale = r_u_max/128 # 將這個長度壓縮到256的尺寸,會有一個scale,實際上這里寫128*sqrt(2)可能會更加直觀for i_u in range(256):for j_u in range(256):x_u = float(i_u - 128)y_u = float(128 - j_u)theta = math.atan2(y_u, x_u)r = math.sqrt(x_u ** 2 + y_u ** 2)r = r * scale # 實際上得到的r,即沒有resize到256×256的圖像尺寸size,并且帶入公式中r_d = (1.0 - math.sqrt(1 - 4.0 * k * r ** 2)) / (2 * k * r + eps) # 對應在原圖(畸變圖)中的rx_d = int(round(r_d * math.cos(theta)))y_d = int(round(r_d * math.sin(theta)))i_d = int(x_d + W / 2.0)j_d = int(H / 2.0 - y_d)if i_d < W and i_d >= 0 and j_d < H and j_d >= 0: # 只有求的的畸變點在原圖中的時候才進行賦值value1 = (i_d - 128.0)/128.0value2 = (j_d - 128.0)/128.0pixel_flow[j_u, i_u, 0] = value1 # mesh中存儲的是對應的r的比值,在進行畸變校正的時候,給定一張這樣的圖,進行找像素即可pixel_flow[j_u, i_u, 1] = value2# 保存成array格式saved_image_file_path = os.path.join(save_path, image_file_name.split('.')[0] + '.npy')pixel_flow = pixel_flow.astype('f2') # 將數據的格式轉換成float16類型, 節省空間# print(saved_image_file_path)# print(pixel_flow)np.save(saved_image_file_path, pixel_flow)returnif __name__ == '__main__':file_list = glob(file_path + '/*.JPEG')m = 32n = int(math.ceil(len(file_list) / float(m))) # 向上取整result = []pool = multiprocessing.Pool(processes=m) # 32進程for i in range(0, len(file_list), n):result.append(pool.apply_async(generate_flow_field, (file_list[i: i+n],)))pool.close()pool.join()復制代碼
在上面的代碼中,我的函數
generate_flow_field(image_list)
需要傳入一個list,然后對于這個list進行操作,之后對操作的結果進行保存
所以,只需要將你需要處理的多個文件,切分成盡量等大小的list,然后再對每一個list,開一個線程進行處理即可
看我上面的主函數
復制代碼
if __name__ == '__main__':file_list = glob(file_path + '/*.JPEG') # 將文件夾下所有的JPEG文件列成一個listm = 32 # 假設CPU有32個核心n = int(math.ceil(len(file_list) / float(m))) # 每一個核心需要處理的list的數目result = []pool = multiprocessing.Pool(processes=m) # 開32線程的線程池for i in range(0, len(file_list), n):result.append(pool.apply_async(generate_flow_field, (file_list[i: i+n],))) # 對每一個list都用上面我們定義的函數進行處理pool.close() # 處理結束之后,關閉線程池pool.join()復制代碼
主要是這樣的兩行代碼,一行是
pool = multiprocessing.Pool(processes=m) # 開32線程的線程池
用來開辟線程池
另外一行是
result.append(pool.apply_async(generate_flow_field, (file_list[i: i+n],))) # 對每一個list都用上面我們定義的函數進行處理
對于線程池,用apply_async()同時跑generate_flow_field這個函數,傳入的參數是:file_list[i: i+n]
實際上apply_async()這個函數的作用是所有的線程同時跑,速度是比較快的
怎么樣,講到這里,是不是學會如何使用pool.apply_async()來進行多線程加速了呢?
總結
以上是生活随笔為你收集整理的python中调用多进程加速处理文件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2005精品书籍-go go go
- 下一篇: python程序开子进程打包成exe文件