python.multiprocessing та “FATAL ERROR (INFADI) MISSING DIRECTORY”


9

Намагаючись робити багатопроцесорну операцію з arcpy, я час від часу стикаюся з цією помилкою:

FATAL ERROR (INFADI)
MISSING DIRECTORY

Я не маю поняття, що викликає цю помилку, і вона руйнує процес python, що робить неможливим отримати прослідкування на ньому. Це відбувається під час запису остаточного растрового виходу з тривалої звукової моделі.

Іноді це супроводжується помилкою

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

Де% Temp проаналізовано коректність і #### є деяким випадковим чотиризначним числом. Це незвично, тому що для кожного процесу є своя робоча область, саме там слід записати більшість файлів.

Проблема не в вхідних даних ... Я можу повторно запустити програму на невдалі входи, і вона запуститься правильно.


До цього я повернусь незабаром, але зараз потрібно працювати над іншою моделлю.
blord-castillo

Відповіді:


6

Ось кілька речей, які потрібно перевірити:

Ви використовуєте курсори? Ви їх випускаєте? Ви намагаєтесь повторно використовувати будь-які об’єкти в різних процесах? Ви ділитесь тим самим тимчасовим розташуванням? Ви займаєтесь обробкою пам'яті?

Загалом, архпія - це просто обгортка навколо об'єктів ком, і будь-який тип багатопроцесорної обробки буде складним.


4

Я виявив, що ця проблема виникає, коли arcpy.env.workspace і arcpy.env.scratchWorkspace однакові для двох різних процесів. Arc записує майже всі проміжні растри до робочої області (або подряпини робочої області) у форматі ESRI GRID. Ви не можете одночасно записати два растри ESRI GRID в один каталог через структуру формату псевдобаз даних (у папці інформації містяться унікальні клавіші для кожного растру).

Я уникнув цієї помилки, призначивши для кожного процесу унікальну робочу область та scratchWorkspace за допомогою тимчасової папки tempfile.mkdtemp.


Я вже використовую унікальні робочі простори, але я подвійно перевіряю, що scratchWorkspace теж унікальний. Я не здогадуюсь, оскільки це записується до директиви% TEMP%.
blord-castillo

Йона прямо на. Я обробляю тисячі растра в одному каталозі через 5 одночасних потоків; встановлення унікальної робочої області для нуля для кожного - єдине рішення, яке працювало для мене. Виведення в унікальні папки, як рекомендують деякі, просто створює більше роботи для подальшого ... врешті-решт, я хочу їх усіх в одному каталозі.
Том

Який біль у спині! Використання унікальної робочої області нуля з багатопроцесорною роботою, але мій бог, керувати додатковими папками, а потім намагатися видалити їх за допомогою arcpy-замків - смішно !!
D_C

3

Я також зіткнувся з цим, і мені ще потрібно знайти корекцію звуку. Моя робота - 1), щоб переконатися, що багатопроцесорна задача є достатньо надійною, щоб перевірити, чи завдання виконані чи ні, а потім створити новий список завдань. 2) заплануйте два сценарії для запуску кожні 10-15 хвилин. Один скрипт містить команду вбити вибрані запущені процеси python, а другий повторно запускає потрібний багатопроцесорний сценарій. По суті, це освіжає багатопроцесорний пул. Сценарій вбивства є приблизно таким:

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, коли намагаюся зберегти та змінити растри в одній папці з декількох потоків / ядер. Призначення підпапки кожному завданню для виходів, схоже, вирішує проблему. Я вважаю, що проблема стосувалася декількох читання / запису в периферійні файли, пов’язані з растром (наприклад, папка "інформація"). Зараз я також застосовую такі заходи безпеки:

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 в одну папку через кілька потоків. Єдиною проблемою, здається, є те, що це уповільнює обробку і фактично приводить до недійсності потоку, оскільки вона пише лише один растр за один раз.
Том
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.