Fiquei me perguntando se alguém da comunidade aqui tentou usar o multiprocessamento para análises espaciais. Ou seja, estou tentando iterar através de uma série de rasters, criar um trabalho de multiprocessamento para cada um e executá-los através de várias etapas de geoprocessamento dentro de uma função def. Algo ao longo das linhas de
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)))
Agora, o multiprocessamento é executado, geralmente para o primeiro lote! No entanto, continuo com vários erros diferentes ao tentar vários conjuntos de dados (mais de 4 arquivos - ou seja, 4 multiprocessamentos principais), incluindo:
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).
e
ERROR 999999: Error executing function.
Failed to copy raster dataset
Failed to execute (ProjectRaster)
Observe no primeiro erro a pasta estranha criada (no local OutFolderDir) associada às estatísticas focais que quase cria uma réplica exata da saída final.
Minha pergunta é baseada na sua experiência: é impossível criar várias etapas de geoprocessamento em uma função de multiprocessamento? Ou preciso integrar essas etapas em suas etapas individuais de geoprocessamento?
ATUALIZAR
Ainda encontrando erros semelhantes - mover as funções de importação para a função def mostrou que
import arcpy
from arcpy.sa import *
Não é possível criar uma saída com uma sintaxe adicionada, avisando que import * não é permitido.
ATUALIZAÇÃO # 2
Sei que esta é uma resposta tardia, mas achei que poderia beneficiar alguém para referência futura à minha solução alternativa que permite que o multiprocessamento funcione com o arcpy. O principal problema que encontrei após retornar a esse problema não é a competição dos módulos arcpy, mas a competição pelo scratchWorkspace que o ArcObjects utiliza para salvar os arquivos temporários. Portanto, considere executar um contador no argumento de análise de multiprocessamento para criar um espaço de trabalho exclusivo para cada processo, ou seja
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
Em seguida, na função principal, crie um diretório temporário específico e atribua um espaço de trabalho exclusivo a cada tarefa de multiprocessamento.
def main(RasterImage,OutFolderDir,Counter)
TempFolder = os.path.join(os.path.dirname(OutFolderDir),'Temp_%s'% (Counter))
os.mkdir(TempFolder)
arcpy.scratchWorkspace = TempFolder
...
Espero que ajude e agradeça a Ragi pela sugestão inicial de usar espaços de trabalho temporários separados - ainda desconcertados com o motivo pelo qual originalmente não funcionou.
Recursos adicionais
R
. Essas não são boas sugestões para o trabalho de uso geral, porque podem ser mais problemas do que valem, mas quando você pode economizar horas de cada vez, repetidamente, o esforço pode valer a pena.Respostas:
Cada conexão do IWorkspace (ou seja, cada conexão de banco de dados) possui afinidade de encadeamento. Dois segmentos não podem compartilhar o mesmo espaço de trabalho. Você pode ter um thread como proprietário do recurso e sincronizar o acesso, mas se você estiver usando funções gp diretas, isso ainda não é uma opção.
A maneira mais fácil (coxa) é criar processos separados e, em seguida, sincronizar vários processos (em oposição à sincronização multithread). Mesmo assim, você deve estar ciente do tipo de espaço de trabalho subjacente. se você não estiver usando o arcsde (uma fonte de dados multiusuário), provavelmente usará uma única fonte de dados do usuário (como personal ou filegdb). Lembre-se de que apenas um processo pode escrever por vez! A sincronização (lame) típica para esses cenários é que cada processo paralelo grava em um espaço de trabalho temporário diferente e, em seguida, você mescla tudo no espaço de trabalho de destino em um único processo.
fonte
Você tem vários threads competindo pelo mesmo recurso.
Tente mover sua instrução 'import arcpy' para o destino do multiprocessamento. Você garantirá que o arcpy esteja trabalhando com seu próprio conjunto de variáveis de ambiente e memória.
Parece absurdo, mas mesmo que você esteja configurando variáveis de ambiente no método de destino Multiprocessos, o python ainda está usando um espaço de memória compartilhada para gerenciar o módulo arcpy e, portanto, quaisquer variáveis que você definir.
O Arcpy não é seguro para threads. Ele sempre foi projetado para ser usado em um único processo. Mas existem soluções alternativas.
Minha sugestão foi importar o arcpy dentro do destino para um novo processo.
fonte