问题背景是这样的,我有一批需要处理的文件,对于每一个文件,都需要调用同一个函数进行处理,相当耗时

有没有加速的办法呢?当然有啦,比如说你将这些文件分成若干批,每一个批次都调用自己写的python脚本进行处理,这样同时运行若干个python程序也可以进行加速

但是,有没有更简单的方法呢?比如说,我一个运行的一个程序里面,同时分为多个线程,然后进行处理?

实际上是有的

大概思路是这样,将这些个文件路径的list,分成若干个,至于分成多少,要看自己cpu核心有多少,比如你的cpu有32核的,理论上就可以加速32倍

直接上代码:

  1. # -*-coding:utf-8-*-
  2. import numpy as np
  3. from glob import glob
  4. import math
  5. import os
  6. import torch
  7. from tqdm import tqdm
  8. import multiprocessing
  9.  
  10. label_path = '/home/ying/data/shiyongjie/distortion_datasets/new_distortion_dataset/train/label.txt'
  11. file_path = '/home/ying/data/shiyongjie/distortion_datasets/new_distortion_dataset/train/distortion_image'
  12. save_path = '/home/ying/data/shiyongjie/distortion_datasets/new_distortion_dataset/train/flow_field'
  13.  
  14. r_d_max = 128
  15. image_index = 0
  16. txt_file = open(label_path)
  17. file_list = txt_file.readlines()
  18. txt_file.close()
  19. file_label = {}
  20. for i in file_list:
  21. i = i.split()
  22. file_label[i[0]] = i[1]
  23.  
  24. r_d_max = 128
  25. eps = 1e-32
  26. H = 256
  27. W = 256
  28.  
  29. def generate_flow_field(image_list):
  30. for image_file_path in ((image_list)):
  31. pixel_flow = np.zeros(shape=tuple([256, 256, 2])) # 按照pytorch中的grid来写
  32. image_file_name = os.path.basename(image_file_path)
  33. # print(image_file_name)
  34. k = float(file_label[image_file_name])*(-1)*1e-7
  35. # print(k)
  36. r_u_max = r_d_max/(1+k*r_d_max**2) # 计算出畸变校正之后的对角线的理论长度
  37. scale = r_u_max/128 # 将这个长度压缩到256的尺寸,会有一个scale,实际上这里写128*sqrt(2)可能会更加直观
  38. for i_u in range(256):
  39. for j_u in range(256):
  40. x_u = float(i_u - 128)
  41. y_u = float(128 - j_u)
  42. theta = math.atan2(y_u, x_u)
  43. r = math.sqrt(x_u ** 2 + y_u ** 2)
  44. r = r * scale # 实际上得到的r,即没有resize到256×256的图像尺寸size,并且带入公式中
  45. r_d = (1.0 - math.sqrt(1 - 4.0 * k * r ** 2)) / (2 * k * r + eps) # 对应在原图(畸变图)中的r
  46. x_d = int(round(r_d * math.cos(theta)))
  47. y_d = int(round(r_d * math.sin(theta)))
  48. i_d = int(x_d + W / 2.0)
  49. j_d = int(H / 2.0 - y_d)
  50. if i_d < W and i_d >= 0 and j_d < H and j_d >= 0: # 只有求的的畸变点在原图中的时候才进行赋值
  51. value1 = (i_d - 128.0)/128.0
  52. value2 = (j_d - 128.0)/128.0
  53. pixel_flow[j_u, i_u, 0] = value1 # mesh中存储的是对应的r的比值,在进行畸变校正的时候,给定一张这样的图,进行找像素即可
  54. pixel_flow[j_u, i_u, 1] = value2
  55.  
  56. # 保存成array格式
  57. saved_image_file_path = os.path.join(save_path, image_file_name.split('.')[0] + '.npy')
  58. pixel_flow = pixel_flow.astype('f2') # 将数据的格式转换成float16类型, 节省空间
  59. # print(saved_image_file_path)
  60. # print(pixel_flow)
  61. np.save(saved_image_file_path, pixel_flow)
  62. return
  63.  
  64. if __name__ == '__main__':
  65. file_list = glob(file_path + '/*.JPEG')
  66. m = 32
  67. n = int(math.ceil(len(file_list) / float(m))) # 向上取整
  68. result = []
  69. pool = multiprocessing.Pool(processes=m) # 32进程
  70. for i in range(0, len(file_list), n):
  71. result.append(pool.apply_async(generate_flow_field, (file_list[i: i+n],)))
  72. pool.close()
  73. pool.join()

在上面的代码中,我的函数

  1. generate_flow_field(image_list)

需要传入一个list,然后对于这个list进行操作,之后对操作的结果进行保存

所以,只需要将你需要处理的多个文件,切分成尽量等大小的list,然后再对每一个list,开一个线程进行处理即可

看我上面的主函数

  1. if __name__ == '__main__':
  2. file_list = glob(file_path + '/*.JPEG') # 将文件夹下所有的JPEG文件列成一个list
  3. m = 32 # 假设CPU有32个核心
  4. n = int(math.ceil(len(file_list) / float(m))) # 每一个核心需要处理的list的数目
  5. result = []
  6. pool = multiprocessing.Pool(processes=m) # 开32线程的线程池
  7. for i in range(0, len(file_list), n):
  8. result.append(pool.apply_async(generate_flow_field, (file_list[i: i+n],))) # 对每一个list都用上面我们定义的函数进行处理
  9. pool.close() # 处理结束之后,关闭线程池
  10. pool.join()

主要是这样的两行代码,一行是

  1. pool = multiprocessing.Pool(processes=m) # 开32线程的线程池

用来开辟线程池

另外一行是

  1. 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中调用多线程加速处理文件的更多相关文章

  1. Python之FTP多线程下载文件之分块多线程文件合并

    Python之FTP多线程下载文件之分块多线程文件合并 欢迎大家阅读Python之FTP多线程下载系列之二:Python之FTP多线程下载文件之分块多线程文件合并,本系列的第一篇:Python之FTP ...

  2. Python之FTP多线程下载文件之多线程分块下载文件

    Python之FTP多线程下载文件之多线程分块下载文件 Python中的ftplib模块用于对FTP的相关操作,常见的如下载,上传等.使用python从FTP下载较大的文件时,往往比较耗时,如何提高从 ...

  3. Django之在Python中调用Django环境

    Django之在Python中调用Django环境 新建一个py文件,在其中写下如下代码: import os if __name__ == '__main__': os.environ.setdef ...

  4. (转)python中调用R语言通过rpy2 进行交互安装配置详解

    python中调用R语言通过rpy2 进行交互安装配置详解(R_USER.R_HOME配置) 2018年11月08日 10:00:11 luqin_ 阅读数:753   python中调用R语言通过r ...

  5. 如何在python中调用C语言代码

    1.使用C扩展CPython还为开发者实现了一个有趣的特性,使用Python可以轻松调用C代码 开发者有三种方法可以在自己的Python代码中来调用C编写的函数-ctypes,SWIG,Python/ ...

  6. Python中基本的读文件和简单数据处理

    Python中基本的读文件和简单数据处理 暂无评论 DataQuest上面的免费课程(本文是Python基础课程部分),里面有些很基础的东西(csv文件读,字符串预处理等),发在这里做记录.涉及下面六 ...

  7. Python中的多线程编程,线程安全与锁(二)

    在我的上篇博文Python中的多线程编程,线程安全与锁(一)中,我们熟悉了多线程编程与线程安全相关重要概念, Threading.Lock实现互斥锁的简单示例,两种死锁(迭代死锁和互相等待死锁)情况及 ...

  8. [Python-MATLAB] 在Python中调用MATLAB的API

    可以参考官方的说明文档: http://cn.mathworks.com/help/matlab/matlab_external/get-started-with-matlab-engine-for- ...

  9. python中的多线程和多进程

    一.简单理解一下线程和进程 一个进程中可有多个线程,线程之间可共享内存,进程间却是相互独立的.打比方就是,进程是火车,线程是火车厢,车厢内人员可以流动(数据共享) 二.python中的多线程和多进程 ...

随机推荐

  1. qt 调用zlib压缩与解压缩功能

    Zlib是一种免费且通用的压缩库,由于Zlib压缩效果比LZW好,而且解压缩速度快,更重要的是商业软件中使用Zlib不需要缴纳版权费,所以很多游戏都使用Zlib压缩资源文件. Zlib是由Jean-l ...

  2. Qt样式表都有哪些属性可以设置

    我们可以在Qt助手中输入Qt Style Sheets Reference然后选择List of Pseudo-States 项查看Qt控件支持的所有状态. 附几个参考学习的博客: https://b ...

  3. python删除指定路径的文件

    import os            import glob                        path =imgDate_listResult            for infi ...

  4. forget stereo step word out8

      1★ stereo st əri əu 立体的   2★ step st əp 后,前妻所生,步骤  

  5. frameset的固定放置模式,不能放入<form runat="server">中

    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="admin_default.as ...

  6. 下载hibenate tools插件(百度搜hibenate tools 下载)

    Eclipse插件的安装和使用1.     在线更新( http://blog.csdn.net/charlies_fu/article/details/5638068)打开eclipse工具,选择H ...

  7. Edit Distance II

    Given two strings S and T, determine if they are both one edit distance apart. Example Given s = &qu ...

  8. C++基础知识:继承

    1.继承的概念 面向对象中的继承指类之间的父子关系子类拥有父类的所有成员变量和成员函数子类就是一种特殊的父类子类对象可以当作父类对象使用子类可以拥有父类没有的方法和属性 2.C++中的访问级别与继承p ...

  9. Centos7部署kubelet(六)

    1.二进制包准备将软件包从linux-node1复制linux-node2.linux-node3中去 [root@linux-node1 ssl]# cd /usr/local/src/kubern ...

  10. Docker(2):快速入门及常用命令

    什么是Docker? Docker 是世界领先的软件容器平台.开发人员利用 Docker 可以消除协作编码时“在我的机器上可正常工作”的问题.运维人员利用 Docker 可以在隔离容器中并行运行和管理 ...