并行保存到netCDF4文件的Python多处理

并行保存到netCDF4文件的Python多处理,python,parallel-processing,multiprocessing,python-multiprocessing,netcdf4,Python,Parallel Processing,Multiprocessing,Python Multiprocessing,Netcdf4,我正在执行一个模拟,希望保存状态向量的快照,并计算不同参数的快照。我有两个要扫描的控制参数(下面示例中的p和a)。因此,我将模拟结果保存为一个netCDF4文件,其中两个维度用于两个控制参数。当我为一个参数集运行模拟时,文件被正确保存,但当我尝试从多处理运行apply_async时,进程结束时的netCDF4不可访问 我的完整代码是这样的,但基本上我要做的是: import multiprocessing as mp import time as timer import netCDF4 imp

我正在执行一个模拟,希望保存状态向量的快照,并计算不同参数的快照。我有两个要扫描的控制参数(下面示例中的p和a)。因此,我将模拟结果保存为一个netCDF4文件,其中两个维度用于两个控制参数。当我为一个参数集运行模拟时,文件被正确保存,但当我尝试从
多处理运行
apply_async
时,进程结束时的netCDF4不可访问

我的完整代码是这样的,但基本上我要做的是:

import multiprocessing as mp
import time as timer
import netCDF4
import numpy as np
def run_sim_for_p_a(p,a,pstep,astep,step,max_time,u0,fname):
    time_ar=np.arange(0,max_time,step)
    u = np.ones((len(time_ar),1024))
    u[0]=u0
    print "Calculating for p,a:",p,a
    for i,t in enumerate(time_ar[1:]):
        u[i+1] = u[i]*np.cos(t)*np.sin(a)*np.sin(p)
    for tstep,t in enumerate(time_ar):
        save_p_a_snapshot(fname,pstep,astep,tstep,p,a,t,u[tstep]) # save the results into the netCDF4 file

def apply_async_and_save_grid(pmin,pmax,fname,
                              Np=10,Na=10,
                              step=None,max_time=500.0,numproc=10):
    start = timer.time()
    setup_p_a_scan(fname) # Setup a netCDF4 file for the simulations
    if step is None:
        step=max_time
    p_range = np.linspace(pmin,pmax,Np)
    init = np.random.random((1024))
    a_range = np.linspace(0,1,Na)
    availble_cpus = int(available_cpu_count() - 2)
    numproc=min(numproc,availble_cpus)
    print "Using",numproc," processors"
    pool = mp.Pool(processes=numproc)
    for i,p in enumerate(p_range):
        for j,a in enumerate(a_range):
            pool.apply_async(run_sim_for_p_a,
                             args = (p,a,i,j,step,max_time,init,fname))
    pool.close()
    pool.join()
    print "Took ",timer.time()-start
if __name__=="__main__":
    apply_async_and_save_grid(1.0,2.0,"test",Np=2,Na=4,step=1.0,max_time=10)

至少有两种可能的方法:

您可以让每个辅助进程将其结果写入自己的netCDF4文件,并让主程序在所有辅助进程完成后合并它们

我不熟悉netCDF格式,但假设可以附加到此类文件中,另一种可能是在启动
apply\u async
之前创建
multiprocessing.Lock
。此锁应添加到辅助进程的参数中。工作进程应该
获取锁,打开netcdf文件,写入并关闭它。然后它应该
释放
锁。这将确保一次只有一个进程将写入netCDF文件

编辑
请参阅关于如何使用
池处理
锁定

的答案。您有多个进程异步运行,不通信,访问同一磁盘文件。?!可能想看这个演讲,是的,进程之间不进行通信,而是将结果保存到同一个磁盘文件中。非常好,我必须添加一个管理器或全局锁,因为我使用了一个工作池,所以我提到了这个线程-@Ohm Excellent find!有一些微妙之处我没有意识到。我已更新我的答案以匹配。