python.multiprocessing และ“ ข้อผิดพลาดของ FATAL (INFADI) MISSING DIRECTORY”


9

ในขณะที่พยายามทำการประมวลผลหลายตัวด้วย arcpy ฉันพบข้อผิดพลาดนี้เป็นครั้งคราว:

FATAL ERROR (INFADI)
MISSING DIRECTORY

ฉันไม่มีเงื่อนงำอะไรที่ทำให้เกิดข้อผิดพลาดนี้และทำให้กระบวนการหลามทำให้เป็นไปไม่ได้ที่จะได้รับการติดตามย้อนกลับ มันเกิดขึ้นขณะเขียนเอาต์พุต raster สุดท้ายจากแบบจำลองเสียงที่ยาว

บางครั้งมันมาพร้อมกับข้อผิดพลาด

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

โดยที่% Temp ถูกแยกวิเคราะห์คำและ #### เป็นตัวเลขสุ่ม 4 หลัก สิ่งนี้ผิดปกติเพราะแต่ละกระบวนการมีพื้นที่ทำงานของตัวเองซึ่งเป็นที่ที่ควรเขียนไฟล์ส่วนใหญ่

ปัญหาไม่ใช่ข้อมูลอินพุต ... ฉันสามารถรันโปรแกรมอีกครั้งบนอินพุตที่ล้มเหลวและมันจะทำงานได้อย่างถูกต้อง


ฉันจะกลับมาที่อันนี้ในไม่ช้า แต่ต้องทำงานกับรุ่นอื่นในตอนนี้
blord-castillo

คำตอบ:


6

นี่คือบางสิ่งที่จะตรวจสอบ:

คุณใช้เคอร์เซอร์หรือไม่ คุณกำลังปล่อยพวกเขา? คุณกำลังพยายามใช้วัตถุใด ๆ ในกระบวนการที่แตกต่างกันหรือไม่? คุณแชร์ตำแหน่งอุณหภูมิเดียวกันหรือไม่ คุณกำลังประมวลผลหน่วยความจำอยู่หรือไม่?

โดยทั่วไป arcpy เป็นเพียง wrapper รอบ ๆ วัตถุ com และการประมวลผลหลายชนิดใด ๆ จะยุ่งยาก


4

ฉันพบว่าปัญหานี้เกิดขึ้นเมื่อ arcpy.env.workspace และ arcpy.env.scratchWorkspace เหมือนกันสำหรับสองกระบวนการที่แตกต่างกัน Arc เขียนแรสเตอร์ระดับกลางเกือบทั้งหมดไปยังพื้นที่ทำงาน (หรือลบพื้นที่ทำงาน) ในรูปแบบ ESRI GRID คุณไม่สามารถเขียน ESRI GRID แรสเตอร์สองตัวในไดเรกทอรีเดียวกันในเวลาเดียวกันได้เนื่องจากโครงสร้างฐานข้อมูลเทียมของรูปแบบ (โฟลเดอร์ข้อมูลเก็บคีย์ที่ไม่ซ้ำสำหรับแต่ละแรสเตอร์)

ฉันได้หลีกเลี่ยงข้อผิดพลาดนี้โดยกำหนดพื้นที่ทำงานเฉพาะและ scratchWorkspace สำหรับแต่ละกระบวนการโดยใช้โฟลเดอร์ชั่วคราว tempfile.mkdtemp


ฉันใช้พื้นที่ทำงานที่ไม่ซ้ำกันแล้ว แต่ฉันจะตรวจสอบอีกครั้งว่า scratchWorkspace นั้นมีลักษณะเฉพาะเช่นกัน ฉันเดาไม่ได้เพราะมันกำลังเขียนถึง% TEMP% diretory
blord-castillo

โยนาห์พูดถูก ฉันกำลังประมวลผลแรสเตอร์นับพันในไดเรกทอรีเดียวใน 5 เธรดพร้อมกัน การตั้งค่าพื้นที่ทำงานรอยขีดข่วนที่ไม่ซ้ำกันสำหรับแต่ละคนเป็นทางออกเดียวที่ได้ผลสำหรับฉัน ส่งออกไปยังโฟลเดอร์ที่ไม่ซ้ำกันตามที่บางคนแนะนำ, เพียงแค่สร้างงานเพิ่มเติมในภายหลัง ... ในที่สุดฉันต้องการพวกเขาทั้งหมดในไดเรกทอรีเดียวกัน
Tom

ช่างเจ็บปวดเหลือเกิน! การใช้พื้นที่ทำงานที่ไม่เหมือนใครกับการทำงานแบบมัลติโพรเซสซิง แต่พระเจ้าของฉันจัดการโฟลเดอร์พิเศษแล้วพยายามลบมันด้วยการล็อคอาร์คpyนั้นไร้สาระ !!
D_C

3

ฉันพบสิ่งนี้ด้วยและยังไม่พบการแก้ไขเสียง งานของฉันคือ 1) เพื่อให้แน่ใจว่างานการประมวลผลหลายอย่างแข็งแกร่งพอที่จะตรวจสอบว่างานเสร็จสมบูรณ์หรือไม่แล้วสร้างรายการงานใหม่ 2) กำหนดเวลาสองสคริปต์เพื่อเปิดใช้งานทุก 10-15 นาที หนึ่งสคริปต์มีคำสั่งเพื่อฆ่าการเลือกการประมวลผลแบบหลามและครั้งที่สองจะเปิดใช้งานสคริปต์การประมวลผลแบบมัลติโพรเซสที่ต้องการ โดยพื้นฐานแล้วสิ่งนี้จะรีเฟรชพูลหลายกระบวนการ สคริปต์ฆ่ามีลักษณะดังนี้:

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


3

ผมต้องยอมรับว่าผมมาถึงจุดนี้เพียง wannabee multithreading แต่บล็อกที่https://pythongisandstuff.wordpress.com/2013/07/31/using-arcpy-with-multiprocessing-%E2%80%93-part -3 / แสดงให้เห็นว่าการรวมarcpy.Exists()ฟังก์ชั่นเป็นกุญแจสำคัญในการทำให้มันเกิดขึ้น


2

ฉันพบว่าฉันได้รับข้อผิดพลาดของ INFADI เมื่อพยายามมีหลายเธรด / แกนบันทึกและแก้ไข rasters ในโฟลเดอร์เดียว การกำหนดโฟลเดอร์ย่อยให้กับแต่ละงานสำหรับผลลัพธ์ดูเหมือนว่าจะแก้ปัญหาได้ ฉันเชื่อว่าปัญหาเกี่ยวข้องกับการอ่าน / เขียนหลาย ๆ ไฟล์ไปยังอุปกรณ์ต่อพ่วงที่เกี่ยวข้องกับแรสเตอร์ (เช่นโฟลเดอร์ "ข้อมูล") ตอนนี้ฉันยังใช้ความระมัดระวังดังต่อไปนี้:

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 หลายรายการในโฟลเดอร์เดียวกันผ่านหลายเธรด ปัญหาเดียวที่ดูเหมือนว่าการทำเช่นนี้จะทำให้การประมวลผลช้าลงและจะทำให้เธรดไม่สามารถใช้งานได้จริงเนื่องจากมันจะเขียนเพียงหนึ่งครั้งเท่านั้น
ทอม
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.