玩蛇网提供最新Python编程技术信息以及Python资源下载!

python关于pool+map+arcgis's py module并行计算疑惑

学习了
《一行 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,multiprocessing
files=['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 1
b.txt readed 1
c.txt readed 2
d.txt readed 2
e.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 1
b.txt readed 1
c.txt readed 1
d.txt readed 1
e.txt readed 1

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

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

引用:How to un-import modules

先回答问题:

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

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

玩蛇网文章,转载请注明出处和文章网址:https://www.iplaypy.com/wenda/wd19819.html

相关文章 Recommend

玩蛇网Python互助QQ群,欢迎加入-->: 106381465 玩蛇网Python新手群
修订日期:2017年05月23日 - 11时04分01秒 发布自玩蛇网

您现在的位置: 玩蛇网首页 > Python问题解答 > 正文内容
我要分享到:

必知PYTHON教程 Must Know PYTHON Tutorials

必知PYTHON模块 Must Know PYTHON Modules