2017-07-14 69 views
4

衆所周知,我們需要在使用if __name__ == '__main__'的Python中運行代碼multiprocessing時保護main()在Python多重處理中使用__name __ =='__ main__'的解決方法

我明白,這是在某些情況下,必要時給予進入主定義的函數,但我不明白這是爲什麼在這種情況下,有必要:

​​

import numpy as np 
from multiprocessing import Pool 
class Something(object): 
    def get_image(self): 
     return np.random.rand(64,64) 

    def mp(self): 
     image = self.get_image() 
     p = Pool(2) 
     res1 = p.apply_async(np.sum, (image,)) 
     res2 = p.apply_async(np.mean, (image,)) 
     print(res1.get()) 
     print(res2.get()) 
     p.close() 
     p.join() 

main.py

from file2 import Something 
s = Something() 
s.mp() 

Something工作所需的所有功能或進口是​​58的一部分。爲什麼子過程需要重新運行main.py

我認爲__name__解決方案不是很好,因爲這阻止了我分發​​的代碼,因爲我無法確定它們是保護它們的主體。 對於Windows沒有解決方法嗎? 是如何解決的軟件包 -

編輯(因爲我從來沒有遇到過不保護我的主要有任何包中的任何問題,他們只是沒有使用多?): 我知道,這是因爲沒有實現fork()的視窗。我只是問,如果有一個黑客讓翻譯在​​開始,而不是main.py,我可以肯定的是​​是自給自足

+3

'if __name__ =='__main __''hack只在Windows上需要,因爲該平臺沒有'fork()'。如果您選擇_any_其他操作系統,則不需要它。 –

+0

OP,只是爲了確認,你在windows上是否正確? –

+1

如果我正確理解你,你正在編寫'file2.py'作爲一個庫,並且你想要支持像'main.py'這樣的用戶代碼(將來可能會被其他人編寫)。不幸的是,我不認爲有什麼辦法可以保護你的用戶免受'multiprocessing'的需求。您可能只需要記錄您的模塊需要將腳本代碼放在'if __name__ ==「__main __」'塊中,以便在模塊導入時不會運行任何內容。 – Blckknght

回答

1

主要模塊導入(但__name__ != '__main__'因爲Windows正試圖以模擬分叉類似的行爲一個沒有分叉的系統multiprocessing沒有辦法知道你沒有在你的主模塊中做任何重要的事情,所以導入完成「以防萬一」來創建一個類似於主進程中的環境如果沒有這樣做,那麼在子進程中可能無法正確執行主副本中發生的各種事件(例如導入,具有持久副作用的配置調用等)。

因此,如果他們不保護他們的__main__,代碼不是多處理安全的(也不是單元測試安全,導入安全等)。 if __name__ == '__main__':保護包裝應該是所有正確的主要模塊的一部分。繼續並分發,並提供關於要求多處理安全主模塊保護的說明。

4

當使用「重生」啓動方法,新工藝是Python解釋是從零開始。對於子流程中的新Python解釋器來說,不可能找出需要導入的模塊,因此它們再次導入主模塊,然後再導入其他所有模塊。這意味着它必須可以導入主模塊而沒有任何副作用。

如果您使用的是與Windows不同的平臺,則可以使用「fork」開始方法,而不會出現此問題。

這就是說,使用if __name__ == "__main__":有什麼問題?它還有很多額外的好處,例如文檔工具將能夠處理您的主要模塊,單元測試更容易等,所以您應該在任何情況下使用它。

1

if __name__ == '__main__'在windows上是需要的,因爲windows沒有進程的「fork」選項。例如,你可以在fork這個進程中,所以父進程將被複制,副本將成爲子進程(並且它將有權訪問你已經在父進程中加載​​的已經導入的代碼)

既然你不能在Windows中分叉,python只是導入父進程導入的所有代碼在子進程中。這會產生類似的效果,但是如果你不執行這個技巧,這個導入將在子進程中再次執行你的代碼(這將使它創建它自己的子進程,等等)。

因此,即使在您的示例中,main.py也會再次導入(因爲所有文件都會再次導入)。 python cant猜測子進程應該導入什麼特定的python腳本。

FYI還有其他的限制,你應該知道像使用全局變量,你可以看到在這裏https://docs.python.org/2/library/multiprocessing.html#windows

相關問題