python关于pool+map+arcgis's py module并行计算疑惑,arcgismodule,学习了《一行 Pytho


学习了
《一行 Python 实现并行化 -- 日常多线程操作的新思路》http://blog.segmentfault.com/caspar/1190000000414339
原作者 Chris https://medium.com/building-things-on-the-internet/40e9b2b36148#66bf-f06f781cb52b 后,
我在用Pool多进程执行并行计算,主要是调用arcgis的py模块,发现一个问题:
我的代码:

files=['E:/select/r0_51x47.txt',       'E:/select/r0_79x77.txt',       'E:/select/r0_89x65.txt',       'e:/select/r0_101x109.txt',       'e:/select/r0_104x88.txt',       'e:/select/r0_127x80.txt',       'e:/select/r0_139x136.txt',       'e:/select/r0_204x209.txt']print ('')print ('###################################')pool_costtime_start= datetime.datetime.now()pool = Pool()#len(files)pool.map(ExtractRidge, files)pool.close()pool.join()print ('Pool Cost time: '+\        str((datetime.datetime.now() - pool_costtime_start).seconds)+\        ' seconds')

len(files)>CPU数(我的是win7+i5),执行过程中某个进程执行到arcgis提供的函数时,会无限期等待着,如下图:


我的解决方法是:直接设置Pool的大小,即

pool=Pool(len(files))

这样就不会出现之前的情况了,这是成功的结果

同样的,我还测试了用

pool=ThreadPool() 或者pool=ThreadPool(len(files))

实现多线程的并行计算。这个就更糟糕了,提示:

提示的函数,z_limit是第三个参数,默认值为“”

arcpy.gp.Fill_sa(dem, fill, "")

但是,在指定进程数的情况下确没问题。我的问题是:

1. 对于CPU密集型的计算来说,进程数是否需要严格指定?例如我的第一个情况下,需要指定进程数才能运算成功,默认由计算机CPU个数来决定的情况就会down机;

2. 是否多线程对于CPU密集型的计算容易出错?因为我用的arcgis模块计算量都很大;

                      **请路过的大神多多指教!**

作为前面几位同学讨论的补充,给出一个可运行例子以说明在multiprocessing模块的进程池中全局对象的生存周期。

foo.py

counter = dict(readed=0)def readfile(filename):    counter['readed']+=1    print '%s readed %d'%(filename,counter['readed'])

main.py

import time,multiprocessingfiles=['a.txt','b.txt','c.txt','d.txt','e.txt']def dowork(filename):    import foo    time.sleep(2)    foo.readfile(filename)if __name__ == '__main__':    pool=multiprocessing.Pool(2)    pool.map(dowork,files)    pool.close()    pool.join()

python main.py输出:

a.txt readed 1b.txt readed 1c.txt readed 2d.txt readed 2e.txt readed 3

dowork被调用5次,但foo.py的全局对象counter只初始化2次。修改dowork方法为

def dowork(filename):    from sys import modules    import foo    time.sleep(2)    foo.readfile(filename)    del modules['foo']

python main.py输出

a.txt readed 1b.txt readed 1c.txt readed 1d.txt readed 1e.txt readed 1

dowork被调用5次,foo.py的全局对象counter初始化5次,这才是我们所期待的结果。

回到题主的情况,很可能arcpy模块引用并改变某全局对象G。当进程池的进程数=文件数,全局对象G相互间无共享,运行正常;当进程池的进程数<文件数,全局对象G被共享,于是厄运开始...

引用:How to un-import modules

先回答问题:

回到您的问题。您在使用 multiprocessing 的时候碰到的问题——由于没有您完整的代码——我推测可能有以下两点原因:

对于您的多线程测试,对问题原因的猜测就更多了,比如代码中有一些非线程安全的全局变量,等等等等,需要根据具体任务代码来看。

编橙之家文章,

评论关闭