python.multiprocessing和“致命错误(INFADI)缺失目录”


9

尝试使用arcpy进行多处理时,偶尔会遇到此错误:

FATAL ERROR (INFADI)
MISSING DIRECTORY

我不知道是什么触发了此错误,它使python进程崩溃,无法对其进行追溯。它是在写入冗长的声音模型的最终栅格输出时发生的。

有时会伴有错误

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

其中%Temp是正确解析的,而####是一些随机的4位数字。这是不寻常的,因为每个进程都有自己的工作区,应在其中写入大多数文件。

问题不在于输入数据...我可以在失败的输入上重新运​​行该程序,它将正确运行。


我很快会回到这个问题,但是现在必须使用其他模型。
blord-castillo 2011年

Answers:


6

这里有一些要检查的东西:

您在使用游标吗?你要释放他们吗?您是否要在不同的流程中重用任何对象?您是否共享相同的临时位置?你在做内存处理吗?

通常,arcpy只是com对象的包装,任何类型的多处理都会很棘手。


4

我发现当两个不同进程的arcpy.env.workspace和arcpy.env.scratchWorkspace相同时会出现此问题。Arc将几乎所有中间栅格都以ESRI GRID格式写入工作区(或临时工作区)。由于格式的伪数据库结构,因此不能同时将两个ESRI GRID栅格写入同一目录(info文件夹为每个栅格保留唯一的键)。

我通过使用临时tempfile.mkdtemp文件夹为每个进程分配唯一的工作区和scratchWorkspace来避免此错误。


我已经使用了唯一的工作区,但我将再次检查scratchWorkspace也是唯一的。我猜不是因为它正在写入%TEMP%目录。
blord-castillo

约拿说的对。我正在通过5个并发线程在一个目录中处理数千个栅格;为每个人设置唯一的临时工作空间是对我有用的唯一解决方案。正如某些人所建议的那样,输出到唯一的文件夹只会为以后创建更多工作...最终我希望它们都在同一目录中。
汤姆(Tom)

背面多么痛苦!使用独特的临时工作区进行多重处理是可行的,但是,我的天哪,管理额外的文件夹,然后尝试使用arcpy锁将其删除很可笑!
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)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.