Мне было интересно, пытался ли кто-нибудь еще в сообществе использовать мультиобработку для пространственного анализа. А именно, я пытаюсь перебрать серию растров, создать многопроцессорное задание для каждого и выполнить их через ряд шагов геообработки в рамках одной функции def. Нечто подобное
def net(RasterImage, OutFolderDir):
arcpy.env.overwriteOutput = True
arcpy.env.workspace = OutFolderDir
DEM_Prj = DEM_Prj.tif
try:
arcpy.ProjectRaster_management(RasterImage, DEM_Prj....
FocalStatistics(DEM_prj....)
...
if __name__ == '__main__':
InputFolder = r'C:\test\somepath'
Output = r'C:\test\somepath2'
arcpy.env.workspace = InputFolder
arcpy.env.scratchWorkspace = r'C:\test.gdb'
fcs = arcpy.ListRasters('*')
pool = multiprocessing.Pool(4)
jobs = []
for fc in fcs:
rIn = os.path.join(InputFolder,fc)
rOut = os.path.join(Output,fc[:-4])
jobs.append(pool.apply_async(net,(rIn, rOut)))
Теперь многопроцессорная обработка выполняется, как правило, для первой партии! Тем не менее, я продолжаю сталкиваться с несколькими различными ошибками при попытке нескольких наборов данных (более 4 файлов - т.е. 4-х ядерная многопроцессорная обработка), включая:
ERROR 010302: Unable to create the output raster: C:\somepath\sr6f8~1\FocalSt_srtm1
ERROR 010067: Error in executing grid expression.
Failed to execute (FocalStatistics).
и
ERROR 999999: Error executing function.
Failed to copy raster dataset
Failed to execute (ProjectRaster)
В первой ошибке обратите внимание на странную папку, которая создается (в расположении OutFolderDir), связанную с фокусной статистикой, которая почти создает точную копию окончательного вывода.
Мой вопрос основан на вашем опыте: нельзя ли создать несколько этапов геообработки в рамках одной многопроцессорной функции? Или мне нужно объединить эти шаги в отдельные этапы геообработки?
ОБНОВИТЬ
По-прежнему возникают похожие ошибки - перемещение функций импорта в функцию def показало, что
import arcpy
from arcpy.sa import *
не может создать вывод с добавленным синтаксическим предупреждением, что импорт * не разрешен.
ОБНОВЛЕНИЕ № 2
Я знаю, что это поздний ответ, но я подумал, что кому-то может пригодиться дальнейшая ссылка на мой обходной путь, который позволяет многопроцессорной обработке работать с arcpy. Основная проблема, которую я обнаружил после возвращения к этой проблеме, - это не конкуренция модулей arcpy, а скорее конкуренция за пространство scratchWorkspace, которое ArcObjects использует для сохранения временных файлов. Поэтому рассмотрите возможность использования счетчика в аргументе разбора многопроцессорности, чтобы создать уникальное пространство для рабочего процесса, т.е.
Counter = 0
for fc in fcs:
rIn = os.path.join(InputFolder,fc)
rOut = os.path.join(Output,fc[:-4])
jobs.append(pool.apply_async(net,(rIn, rOut,Counter)))
Counter += 1
Затем в главной функции создайте конкретный временный каталог и назначьте уникальное пространство scratchWorkspace для каждой многопроцессорной задачи.
def main(RasterImage,OutFolderDir,Counter)
TempFolder = os.path.join(os.path.dirname(OutFolderDir),'Temp_%s'% (Counter))
os.mkdir(TempFolder)
arcpy.scratchWorkspace = TempFolder
...
Надеюсь, что это помогает, и спасибо Ragi за первоначальное предложение использовать отдельные временные рабочие пространства - все еще сбит с толку, почему он изначально не работал.
Дополнительные ресурсы
R
. Это не очень хорошие предложения для работы общего назначения, потому что они могут доставлять больше хлопот, чем они того стоят, но если вы можете сэкономить часы за раз, усилия могут окупиться.Ответы:
Каждое соединение IWorkspace (то есть каждое соединение с базой данных) имеет сходство потоков. Два потока не могут использовать одно и то же рабочее пространство. Вы можете иметь один поток, владеющий ресурсом, и затем синхронизировать доступ, но если вы собираетесь использовать прямые функции gp, то это даже не вариант.
Самый простой (неэффективный) способ - создать отдельные процессы, а затем выполнить многопроцессную синхронизацию (в отличие от многопоточной синхронизации). Даже тогда вы должны знать о базовом типе рабочего пространства. если вы не используете arcsde (многопользовательский источник данных), вы, вероятно, будете использовать однопользовательский источник данных (например, personal или filegdb). Тогда помните, что это означает, что только один процесс может писать одновременно! Типичная (хромая) синхронизация для этих сценариев состоит в том, что каждый параллельный процесс записывает в отдельное временное рабочее пространство, а затем вы объединяете все это в целевое рабочее пространство в одном процессе.
источник
У вас есть несколько потоков, конкурирующих за один и тот же ресурс.
Попробуйте переместить ваш оператор import arcpy в цель многопроцессорной обработки. Вы убедитесь, что arcpy работает со своим собственным набором переменных окружения и памяти.
Это звучит абсурдно, но даже если вы устанавливаете переменные среды в целевом методе Multiprocess, python по-прежнему использует пространство общей памяти для управления модулем arcpy и, следовательно, любыми переменными, которые вы устанавливаете.
Arcpy не является потокобезопасным. Он всегда был предназначен для использования в одном процессе. Но есть обходные пути.
Мое предложение состояло в том, чтобы импортировать arcpy в пределах цели для нового процесса.
источник