0

상태 벡터의 스냅 샷을 저장하고 다른 매개 변수에 대해 수행 할 시뮬레이션을 수행하고 있습니다. 나는 스캔 할 두 개의 제어 매개 변수 (p와 a는 예제)를 가지고있다. 따라서 하나의 netCDF4 파일에 대한 시뮬레이션 결과를 저장합니다.이 파일에서 두 개의 치수가 두 개의 제어 매개 변수에 대한 것입니다. 한 매개 변수 집합에 대한 시뮬레이션을 실행하면 파일이 올바르게 저장되지만 을 multiprocessing에서 실행하려고하면 프로세스가 끝날 때 netCDF4에 액세스 할 수 없습니다.netCDF4 파일에 병렬 저장하는 파이썬 다중 처리

내 전체 코드는이 github repository에서이지만, 기본적으로 난 할 노력하고있어 이것이다 :

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) 
+1

여러 개의 프로세스가 비동기 적으로 실행되고 있고, * * 통신 중이며 동일한 디스크 파일에 액세스하지 못했습니다. 이 대화 [Concurrency에 대한 Keynote] (https://www.youtube.com/watch?v=9zinZmE3Ogk) – wwii

+0

예, 프로세스는 서로 통신하지 않지만 결과는 동일한 디스크 파일에 저장합니다. – Ohm

답변

1

적어도 두 가지 방법이 있습니다

당신은 각 작업자 프로세스 쓰기를 가질 수는 그 결과를 자체 netCDF4 파일에 저장하고 모든 프로그램이 끝나면 주 프로그램을 병합하도록합니다.

netCDF 형식에 익숙하지 않지만 이러한 파일에 추가 할 수 있다고 가정하면 apply_async을 시작하기 전에 multiprocessing.Lock을 생성 할 수 있습니다. 이 잠금은 작업자 프로세스 의 매개 변수에 추가해야합니다. 작업자 프로세스는 잠금을 acquire해야하고, netcdf 파일을 열고, 쓰기 및 닫기를 수행해야합니다. 그럼 자물쇠가 release해야합니다. 이렇게하면 한 번에 하나의 프로세스 만 netCDF 파일에 쓰게됩니다.

편집는 : PoolLock을 처리하는 방법에 this question에 대한 답을 참조하십시오.

+0

우수, 관리자 나 글로벌 잠금을 추가해야했습니다. 작업자 풀을 사용 했으므로이 스레드를 참조했습니다. - https://stackoverflow.com/questions/25557686/python-sharing-a- 프로세스 간 잠금 – Ohm

+0

@Ohm Excellent find! 몇 가지 미묘한 차이가 있습니다. 내가 풀지 못했던'Pool'과'Lock'. 일치하도록 내 답변을 업데이트했습니다. –

관련 문제