python.multiprocessing 및“치명적 오류 (INFADI) 누락 된 디렉토리”


9

arcpy로 다중 처리를 시도하는 동안 때때로이 오류가 발생합니다.

FATAL ERROR (INFADI)
MISSING DIRECTORY

이 오류를 발생시키는 원인에 대한 단서가 없으며 파이썬 프로세스가 충돌하여 역 추적을 할 수 없습니다. 긴 사운드 모델에서 최종 래스터 출력을 쓰는 동안 발생합니다.

때때로 오류가 발생합니다

Unable to write BND file for %TEMP%\ras####

여기서 % Temp는 관련성이 분석되고 ####은 임의의 4 자리 숫자입니다. 각 프로세스마다 대부분의 파일을 작성해야하는 자체 작업 공간이 있기 때문에 이는 드문 일입니다.

문제는 입력 데이터가 아닙니다 ... 실패한 입력에서 프로그램을 다시 실행할 수 있으며 올바르게 실행됩니다.


나는 이것으로 곧 돌아올 것이지만 지금은 다른 모델에서 작업해야합니다.
blord-castillo 님

답변:


6

확인해야 할 사항은 다음과 같습니다.

커서를 사용하고 있습니까? 당신은 그들을 발표하고 있습니까? 다른 프로세스에서 객체를 재사용하려고합니까? 같은 임시 위치를 공유하고 있습니까? 메모리 처리 중입니까?

일반적으로 arcpy는 com 객체를 감싸는 래퍼 일 뿐이며 모든 유형의 멀티 프로세싱이 까다로울 수 있습니다.


4

이 문제는 arcpy.env.workspace와 arcpy.env.scratchWorkspace가 서로 다른 두 프로세스에서 동일 할 때 발생합니다. Arc는 거의 모든 중간 래스터를 ESRI GRID 형식으로 작업 공간 (또는 스크래치 작업 공간)에 씁니다. 형식의 유사 데이터베이스 구조로 인해 두 개의 ESRI GRID 래스터를 동시에 같은 디렉토리에 쓸 수 없습니다 (정보 폴더에는 각 래스터마다 고유 한 키가 있습니다).

임시 tempfile.mkdtemp 폴더를 사용하여 각 프로세스에 고유 한 작업 공간과 scratchWorkspace를 할당하여이 오류를 피했습니다.


이미 고유 한 작업 영역을 사용하고 있지만 scratchWorkspace도 고유한지 다시 확인합니다. 나는 그것이 % TEMP % diretory에 쓰고 있기 때문에 추측하지 않고있다.
blord-castillo

요나가 나왔습니다. 5 개의 동시 스레드에 걸쳐 단일 디렉토리에서 수천 개의 래스터를 처리하고 있습니다. 각 작업마다 고유 한 스크래치 작업 영역을 설정하는 것이 저에게 효과적이었습니다. 일부 사람들이 권장 한 것처럼 고유 폴더로 출력하면 나중에 더 많은 작업이 생성됩니다. 결국 동일한 폴더에 모두 저장하고 싶습니다.
Tom

뒷면이 얼마나 아파요! 멀티 프로세싱과 함께 독특한 스크래치 작업 공간을 사용했지만 추가 폴더를 관리 한 다음 arcpy lock으로 삭제하려고하는 것은 어리 석습니다!
D_C

3

나는 이것도 만났고 아직 소리 수정을 찾지 못했습니다. 내 해결 방법은 1) 다중 처리 작업이 작업이 완료되었는지 확인한 다음 새 작업 목록을 만들 수있을 정도로 강력하다는 것입니다. 2) 10-15 분마다 두 개의 스크립트가 실행되도록 예약하십시오. 하나의 스크립트에는 실행중인 python 프로세스를 죽이는 명령이 포함되어 있으며 두 번째 스크립트는 원하는 다중 처리 스크립트를 다시 시작합니다. 기본적으로 다중 처리 풀을 새로 고칩니다. kill 스크립트는 다음과 같습니다.

def read_pid():
    inFile = open("E:/temp/pid.csv")
    for line in inFile:
        pid = str(line)
    inFile.close()
    return pid

def kill():
    if os.path.exists("E:/temp/pid.csv")==True:
        pid = read_pid()
        PROCESS_TERMINATE=1
        handle = ctypes.windll.kernel32.OpenProcess(PROCESS_TERMINATE,False,pid)
        ctypes.windll.kernel32.TerminateProcess(handle,-1)
        ctypes.windll.kernel32.CloseHandle(handle)
    else:
        return

원하는 스크립트를 시작할 때마다 PID를 csv에 씁니다.



2

여러 스레드 / 코어가 하나의 폴더에 래스터를 저장하고 수정하려고 할 때 INFADI 오류가 발생했습니다. 출력을 위해 각 작업에 하위 폴더를 할당하면 문제가 해결되는 것 같습니다. 문제는 래스터와 관련된 주변 파일 (예 : "info"폴더)에 대한 다중 읽기 / 쓰기와 관련이 있다고 생각합니다. 나는 또한 다음과 같은 예방 조치를 취합니다.

import arcpy,multiprocessing,random

def run(foo,c):
    tempFolder = os.path.join("Z:/temp/",'temp_%s'%(str(c)))
    if not os.path.exists(tempFolder): os.mkdir(tempFolder)
    arcpy.env.scratchWorkspace = tempFolder
    arcpy.env.Workspace = tempFolder

    # create unique object in memory, run task, then delete unique object in memory
    tempMem = str(rnd)
    try:arcpy.Delete_management(tempMem)
    except:pass

    <tasks> #output to appropriate subfolder

    arcpy.Delete_management(tempMem)

if __name__ == '__main__':
    cores = 3
    pool = multiprocessing.Pool(cores)
    count = 0
    for foo in bar:
        pool.apply_async(run,(foo,c))
        count +=1
    pool.close()
    pool.join()

여러 스레드를 통해 여러 GRID를 동일한 폴더에 쓰는 경우 오류가 발생하지 않는 것 같습니다. 유일한 문제는 그렇게하면 처리 속도가 느려지고 스레딩이 사실상 무효화된다는 것입니다. 한 번에 하나의 래스터 만 작성하기 때문입니다.
Tom
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.