Windows下面的multiprocessing跟Linux下面略有不同,Linux下面基于fork,fork之后所有的本地變量都復(fù)制一份,因此可以使用任意的全局變量;在Windows下面,多進(jìn)程是通過啟動(dòng)新進(jìn)程完成的,所有的全局變量都是重新初始化的,在運(yùn)行過程中動(dòng)態(tài)生成、修改過的全局變量是不能使用的。multiprocessing內(nèi)部使用pickling傳遞map的參數(shù)到不同的進(jìn)程,當(dāng)傳遞一個(gè)函數(shù)或類時(shí),pickling將函數(shù)或者類用所在模塊+函數(shù)/類名的方式表示,如果對(duì)端的Python進(jìn)程無法在對(duì)應(yīng)的模塊中找到相應(yīng)的函數(shù)或者類,就會(huì)出錯(cuò)。當(dāng)你在Interactive Console當(dāng)中創(chuàng)建函數(shù)的時(shí)候,這個(gè)函數(shù)是動(dòng)態(tài)添加到main模塊中的,在重新啟動(dòng)的新進(jìn)程當(dāng)中不存在,所以會(huì)出錯(cuò)。當(dāng)不在Console中,而是在獨(dú)立Python文件中運(yùn)行時(shí),你會(huì)遇到另一個(gè)問題:由于你下面調(diào)用multiprocessing的代碼沒有保護(hù),在新進(jìn)程加載這個(gè)模塊的時(shí)候會(huì)重新執(zhí)行這段代碼,創(chuàng)建出新的multiprocessing池,無限調(diào)用下去。解決這個(gè)問題的方法是永遠(yuǎn)把實(shí)際執(zhí)行功能的代碼加入到帶保護(hù)的區(qū)域中:
from multiprocessing import Pool
def f(x):
return x*x
if __name__ == '__main__':
pool = Pool(processes=4)
r=pool.map(f, range(100))
pool.close()
pool.join()
注意if __name__ == '__main__'這一行,當(dāng)模塊從import當(dāng)中加載的時(shí)候這行保證下面的代碼不會(huì)執(zhí)行。
轉(zhuǎn)自鏈接:https://www.zhihu.com/question/39032759/answer/107049302