Python Pool.map() — локально работает, на сервере сбой

#python #windows #server #multiprocessing #arcpy

#python #Windows #сервер #многопроцессорная обработка #arcpy

Вопрос:

Я исследовал многие pool.map на SO и до сих пор не могу найти ничего, что намекает на мою проблему.

У меня есть if __name__ == '__main__' в каждом файле .py. У меня есть freeze_support() в каждом файле .py, который содержит import multiprocessing , я все еще не понимаю, что происходит. Я freeze_support() переместил свой код с теми же неудачными результатами.

Скрипт A вызывает скрипт B, скрипт B вызывает скрипт C (где происходит многопроцессорная обработка). Локально этот сценарий работает отлично, но когда я загружаю его на компьютер с Windows Server 2008, начинают происходить странные вещи.

На сервере я вижу первую итерацию, напечатанную в интерпретаторе, но затем она возвращается к сценарию B и продолжает обработку. В списке для скрипта C. есть еще 51 элемент.

Код скрипта B:

 if not arcpy.Exists(MergedDataFC):
    ScriptC.intersect_main(input1, input2) 

if not arcpy.Exists(MergedDataSHP):
    shpList = arcpy.ListFields(*.shp) # output of multiprocess
    # Merge all shapefiles into single shapefile
    # Being executed before the multiprocess finishes all 52 items
  

Скрипт C-код:

 import multiprocessing as mp

def intersect_main(input1,input2):      
try: 
    mp.freeze_support()
    # Create a list of states for input1 polygons  
    log.log("Creating Polygon State list...")  
    fldList = arcpy.ListFields(input1) 
    flds = [fld.name for fld in fldList]
    idList = []  
    with arcpy.da.SearchCursor(input1, flds) as cursor:  
        for row in cursor:  
            idSTATE = row[flds.index("STATE")]
            idList.append(idSTATE)  

    idList = set(idList)
    log.log("There are "   str(len(idList))   " States (polygons) to process.")  

    log.log("Sending to pool")  
    # declare number of cores to use, use 1 less than the max  
    cpuNum = mp.cpu_count() -1

    # Create the pool object  
    pool = mp.Pool(processes=cpuNum)  

    # Fire off list to worker function.  
    # res is a list that is created with what ever the worker function is returning
    log.log ("Entering intersectWork")  
    res = pool.map((intersectWork(input1, input2, idSTATE)),idList)
    pool.close()  
    pool.join()  

    # If an error has occurred report it  
    if False in res:  
        log.log ("A worker failed!")  
        log.log (strftime('[%H:%M:%S]', localtime()))
        raise Exception
    else:
        log.log("Finished multiprocessing!")
        log.log (strftime('[%H:%M:%S]', localtime()))  
except Exception, e:
    tb = sys.exc_info()[2]   
    # Geoprocessor threw an error 
    log.log("An error occurred on line "   str(tb.tb_lineno)) 
    log.log (str(e))

def intersectWork(input1,input2, idSTATE):  
try:  
    if idSTATE == None:
        query = "STATE IS NULL"
        idSTATE = 'pr'
    else:
        query = "STATE = '"   idSTATE   "'"

    DEMOlayer = arcpy.MakeFeatureLayer_management(input1,"input1_"   idSTATE)

    log.log (query)
    arcpy.SelectLayerByAttribute_management(DEMOlayer,"NEW_SELECTION",query)  

    # Do the Intersect  
    outFC = r'C:/EclipseWorkspace'   '/INTER_'   idSTATE.upper()   '.shp'
    strIntersect = str(DEMOlayer)   ";"   str(input2)
    arcpy.Intersect_analysis(strIntersect, outFC, "ALL", "", "LINE")
    return True  
except:  
    # Some error occurred so return False 
    log.log(arcpy.GetMessage(2))
    return False

if __name__ == '__main__':
    intersect_main(input1, input2)
  

Редактировать

Все данные на сервере хранятся локально, никакой обработки по сети.

Ответ №1:

Проблема заключалась в том, что полный путь к данным не был должным образом передан в pool.map() на сервере из предыдущих модулей. Мне пришлось добавить все пути к файлам в инструкции import. Выглядит не очень элегантно, но работает.