Ich habe mich gefragt, ob irgendjemand in der Community hier versucht hat, Multi-Processing für räumliche Analysen zu verwenden. Ich versuche nämlich, eine Reihe von Rastern zu durchlaufen, für jeden einen Multiprocessing-Job zu erstellen und sie durch eine Reihe von Geoverarbeitungsschritten innerhalb einer Def-Funktion zu führen. Etwas in der Art von
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)))
Jetzt läuft die Mehrfachverarbeitung, normalerweise für die erste Charge! Beim Versuch, mehrere Datensätze (mehr als 4 Dateien - dh 4 Kern-Multiprozessoren) zu verarbeiten, treten jedoch immer wieder verschiedene Fehler auf, darunter:
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).
und
ERROR 999999: Error executing function.
Failed to copy raster dataset
Failed to execute (ProjectRaster)
Beachten Sie im ersten Fehler den seltsamen Ordner, der erstellt wird (am Speicherort von OutFolderDir) und der Fokusstatistik zugeordnet ist, die nahezu eine exakte Kopie der endgültigen Ausgabe erstellt.
Meine Frage basiert auf Ihren Erfahrungen. Ist es unmöglich, mehrere Geoverarbeitungsschritte in einer Multiprocessing-Funktion zu erstellen? Oder muss ich diese Schritte in ihre einzelnen Geoverarbeitungsschritte unterteilen?
AKTUALISIEREN
Immer noch ähnliche Fehler aufgetreten - das Verschieben der Importfunktionen in die def-Funktion hat dies gezeigt
import arcpy
from arcpy.sa import *
Es kann keine Ausgabe mit einer hinzugefügten Syntax-Warnung erstellt werden, dass der Import * nicht zulässig ist.
UPDATE # 2
Ich weiß, dass dies eine verspätete Antwort ist, aber ich dachte, es könnte jemand anderem zugute kommen, wenn ich in Zukunft auf meine Problemumgehung zurückgreifen möchte, die es ermöglicht, dass Multiprocessing mit Arcpy funktioniert. Das Hauptproblem, das ich nach der Rückkehr zu diesem Problem festgestellt habe, ist nicht die Konkurrenz der arcpy-Module, sondern die Konkurrenz um den scratchWorkspace, den ArcObjects zum Speichern der temporären Dateien verwendet. Ziehen Sie daher in Betracht, einen Zähler für das Multiprocessing-Parsing-Argument auszuführen, um einen eindeutigen scratchWorkspace für jeden Prozess zu erstellen, d. H
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
Erstellen Sie dann in der Hauptfunktion ein bestimmtes temporäres Verzeichnis und weisen Sie jeder Multiprozessor-Aufgabe einen eindeutigen scratchWorkspace zu.
def main(RasterImage,OutFolderDir,Counter)
TempFolder = os.path.join(os.path.dirname(OutFolderDir),'Temp_%s'% (Counter))
os.mkdir(TempFolder)
arcpy.scratchWorkspace = TempFolder
...
Hoffe das hilft und danke an Ragi für den anfänglichen Vorschlag, separate temporäre Arbeitsbereiche zu verwenden - immer noch ratlos, warum es ursprünglich nicht funktioniert hat.
Zusätzliche Ressourcen
R
. Dies sind keine guten Vorschläge für allgemeine Arbeiten, da sie mehr Mühe bereiten als sie wert sind. Wenn Sie jedoch mehrmals Stunden auf einmal sparen können, könnte sich der Aufwand lohnen.Antworten:
Jede IWorkspace-Verbindung (dh jede Datenbankverbindung) hat eine Thread-Affinität. Zwei Threads können nicht denselben Arbeitsbereich gemeinsam nutzen. Sie können die Ressource einem Thread gehören lassen und dann den Zugriff synchronisieren. Wenn Sie jedoch gerade GP-Funktionen verwenden, ist dies sogar keine Option.
Am einfachsten (lahmsten) ist es, separate Prozesse zu erstellen und dann eine Synchronisation mit mehreren Prozessen durchzuführen (im Gegensatz zur Synchronisation mit mehreren Threads). Auch dann sollten Sie den zugrunde liegenden Arbeitsbereichstyp kennen. Wenn Sie nicht arcsde (eine Mehrbenutzer-Datenquelle) verwenden, verwenden Sie wahrscheinlich eine einzelne Benutzer-Datenquelle (wie personal oder filegdb). Dann denken Sie daran, dass immer nur ein Prozess gleichzeitig schreiben kann! Die typische (lahme) Synchronisation für diese Szenarien besteht darin, dass jeder parallele Prozess in einen anderen temporären Arbeitsbereich schreibt und Sie dann alles in Ihrem Zielarbeitsbereich in einem einzigen Prozess zusammenführen.
quelle
Sie haben mehrere Threads, die um dieselbe Ressource konkurrieren.
Versuchen Sie, die Anweisung 'import arcpy' in das Ziel der Mehrfachverarbeitung zu verschieben. Sie stellen sicher, dass arcpy mit einem eigenen Satz von Umgebungsvariablen und Speicher arbeitet.
Es klingt absurd, aber obwohl Sie Umgebungsvariablen in der Multiprocess-Zielmethode festlegen, verwendet Python immer noch einen gemeinsam genutzten Speicherbereich, um das Arcpy-Modul und daher alle von Ihnen festgelegten Variablen zu verwalten.
Arcpy ist nicht threadsicher. Es war immer dafür gedacht, innerhalb eines einzigen Prozesses verwendet zu werden. Es gibt jedoch Problemumgehungen.
Mein Vorschlag war, arcpy innerhalb des Ziels für den neuen Prozess zu importieren.
quelle