[Python] python实现多进程任务—以读取grib写入nc为例

[复制链接]

在进行大量数据的I/O操作时,程序会花费较多的时间。为加快程序的运行速度,在python中可使用多进程,利用多核CPU的资源提高效率。这里,请注意区分多进程和多线程的概念(进程可以简单的理解为一个可以独立运行的程序单位,它是线程的集合,进程就是有一个或多个线程构成的)。

8 c* X) j3 X5 p* p2 p; Z; h' R

Python提供了非常好用的多进程包multiprocessing,只需要定义一个函数,Python会完成其他所有事情。借助这个包,可以轻松完成从单进程到并发执行的转换。multiprocessing支持子进程、通信和共享数据、执行不同形式的同步,提供了Process、Queue、Pipe、Lock等组件。

下面以一个数据io操作为例,原始数据文件为4个待读取操作的grib文件,读取其中的数据写入到新的nc文件中,分别使用单进程和多进程进行操作,来展示多进程的性能。

6 |0 ~$ z+ {( c6 B: O7 L* Y

e58f2d7e0015de350f1a2628099a5234.png


, ~/ j( _: o8 d; h9 b. U

简单的讲,我们只需把我们所需要的操作,全部封装成一个函数,然后调用该函数,传入相应的参数,设置好实现多进程。

[Python] 纯文本查看 复制代码
 pool = multiprocessing.Pool(processes=1) #设置多进程池
 for file infiles_list:
     print(file)
     msg=file   #传递参数
     pool.apply_async(write_nc,(msg, )) #调用我自定义的write_nc函数,读取grib文件的数据,写入nc文件中。
 pool.close() #这里的pool.close()是说关闭pool,使其不在接受新的(主进程)任务
 pool.join() #这里的pool.join()是说:主进程阻塞后,让子进程继续运行完成,子进程运行完后,再把主进程全部关掉。
代码如下:* c7 q9 z* ?' G6 m: q# z1 p
[Python] 纯文本查看 复制代码
import pygrib as pg
import netCDF4 as nc
import os
from glob import glob
import multiprocessing
import datetime
 
def write_nc(file):
    output_dir='./grib_file'
    i=1
    ncname=output_dir+'/'+file[-14:-5]+'.nc'
    #创建nc文件
    if os.path.exists(ncname):
      os.remove(ncname)
 
    #创建维度
    f =nc.Dataset(ncname,'w',format = 'NETCDF4')
    f.createDimension('time',91)
    f.createDimension('latitude',1801)
    f.createDimension('longitude',3600)
 
    lon_nc =f.createVariable('lon', 'f4', dimensions=('latitude','longitude'))
    lon_nc.units  = "degrees east"   # 添加变量属性
    lat_nc = f.createVariable('lat','f4', dimensions=('latitude','longitude'))
    lat_nc.units  = "degrees north"   # 添加变量属性
    msl_nc =f.createVariable('msl', 'f4',dimensions=('latitude','longitude','time'),zlib=True,least_significant_digit=1)
    msl_nc.units='pa'、
 
    #读取grib文件
    data=pg.open(file)
    print("正在读取:",file)
    msl_data =data.select(name='2 metre temperature')[0]
    msl= msl_data.values
    lat,lon=msl_data.latlons()
 
    lon_nc[...]=lon
    lat_nc[...]=lat
    msl_nc[:,:,i]=msl
    i=i+1
    f.close()
    print("写入完成,结束!")
 
if __name__=="__main__":
    starttime =datetime.datetime.now()
    src_dir='./grib_file'
    files_list=glob(src_dir+'/*')
    pool =multiprocessing.Pool(processes=1)
    for file infiles_list:
        print(file)
        msg=file
       pool.apply_async(write_nc,(msg, ))
    pool.close()
    pool.join()
 
    endtime =datetime.datetime.now()
    print("程序用时:")
    print (endtime -starttime)
; t) d7 X4 z/ z( n' G
实验结果:

单进程设置(processes=1),运行该程序,运行时间为17.7s。

多进程设置(processes=4),运行时间只需要5.0s,大约为原时间的1/4。

核的多少取决于你计算机有多少可用cpu,在很多情况下,使用多进程可大大提高效率。


7 f3 U  E% {; ~" v  X+ a; s

以下全文代码均已发布至和鲸社区,点击下面链接前往,可一键fork跑通:

游客,如果您要查看本帖隐藏内容请回复

1 i% I3 s) O& J4 P+ l' q* f3 l5 g: M
回复

举报 使用道具

相关帖子

全部回帖
暂无回帖,快来参与回复吧
懒得打字?点击右侧快捷回复 【吾爱海洋论坛发文有奖】
您需要登录后才可以回帖 登录 | 立即注册
怀特景愚
活跃在2022-11-8
快速回复 返回顶部 返回列表