python多进程调用方(以及被调用方)在windows XP上多次调用

python多进程调用方(以及被调用方)在windows XP上多次调用,python,windows-xp,multiprocess,Python,Windows Xp,Multiprocess,可能重复: 我试图使用python多进程来并行化web抓取,但我发现调用多进程的应用程序被多次实例化,而不仅仅是我想要调用的函数(这对我来说是个问题,因为调用者对一个实例化缓慢的库有一些依赖关系——失去了并行性带来的大部分性能收益) 我做错了什么,或者如何避免 my_app.py: from url_fetcher import url_fetch, parallel_fetch import my_slow_stuff my_slow_stuff.py: if __name__ == '_

可能重复:

我试图使用python多进程来并行化web抓取,但我发现调用多进程的应用程序被多次实例化,而不仅仅是我想要调用的函数(这对我来说是个问题,因为调用者对一个实例化缓慢的库有一些依赖关系——失去了并行性带来的大部分性能收益)

我做错了什么,或者如何避免

my_app.py:

from url_fetcher import url_fetch, parallel_fetch
import my_slow_stuff
my_slow_stuff.py:

if __name__ == '__main__':
    import datetime
    urls = ['http://www.microsoft.com'] * 20
    results = parallel_fetch(urls, fn=url_fetch)
    print([x[:20] for x in results])

class MySlowStuff(object):
    import time
    print('doing slow stuff')
    time.sleep(0)
    print('done slow stuff')
url_fetcher.py:

import multiprocessing
import urllib

def url_fetch(url):
    #return urllib.urlopen(url).read()
    return url

def parallel_fetch(urls, fn):
    PROCESSES = 10
    CHUNK_SIZE = 1
    pool = multiprocessing.Pool(PROCESSES)
    results = pool.imap(fn, urls, CHUNK_SIZE)
    return results

if __name__ == '__main__':
    import datetime
    urls = ['http://www.microsoft.com'] * 20
    results = parallel_fetch(urls, fn=url_fetch)
    print([x[:20] for x in results])
部分输出:

$ python my_app.py
doing slow stuff
done slow stuff
doing slow stuff
done slow stuff
doing slow stuff
done slow stuff
doing slow stuff
done slow stuff
doing slow stuff
done slow stuff

用于Windows的Python多处理模块的行为略有不同,因为Python没有在此平台上实现
os.fork()
。特别是:

主模块的安全导入

确保新的Python解释器可以安全地导入主模块,而不会产生意外的副作用(例如启动新进程)

在这里,全局
类MySlowStuff
总是由Windows上新启动的子进程进行计算。要解决此问题,仅当
类MySlowStuff
的名称=时,才应定义
类MySlowStuff


有关更多详细信息,请参阅。

windows上的多处理模块的工作方式与Unix/Linux中的不同。在Linux上,它使用fork命令,所有上下文都会复制/复制到新进程,就像在fork时一样

windows上不存在系统调用fork,并且多处理模块必须创建一个新的python进程并再次加载所有模块,这就是为什么在windows上使用多处理时,on会强制您使用
if uuuuuuu name uuuuuu=='\uuuuuu main_uuu'
技巧的原因

这种情况的解决方案是使用线程。这种情况是一个IO绑定的进程,而避免GIL问题的os多处理的优势并不影响您


更多信息在

你在Windows上观察到了吗?是的,我是。事实上,在我的Linux服务器上,它没有表现出这种行为。谢谢,你一提到Windows,我就知道我会(mis)阅读该部分时,我会认为它与被调用方有关。谢谢,尽管问题中没有说明,但我还有其他任务要完成,例如zlib解压和xml解析,这使我使用多进程而不是线程。