簡體   English   中英

導入模塊的多處理不起作用

[英]Multiprocessing from imported module doesn't work

我在導入模塊時遇到了多處理的問題,可以用下面的例子來表示。

我有一個名為tmp1.py的模塊,其內容如下:

from multiprocessing import Pool

def mul2(x):
    return [a*2 for a in x]

def calculate(func, x):
    r = []
    if __name__ == '__main__':
        p = Pool(2)
        r.append(p.map(func, x))
        p.close(), p.join()
    return r

我將它導入到另一個文件tmp2.py中,內容如下:

import tmp1

inputs = [[1, 2, 3],
          [4, 5, 6],
          [7, 8, 9]]    

result = tmp1.calculate(tmp1.mul2, inputs)
print(result)

運行它后我期望的是輸入的值乘以 2。但是,在我運行它之后,我得到的只是一個空列表。 我在 Windows,python 3.10 上工作。

如果我將tmp1.py的所有內容復制粘貼到tmp2.py並調整函數調用,它就可以正常工作。

問題出在哪里?

if __name__ == '__main__':是控制在使用spawn方法創建新進程的平台(如 Windows)上創建新進程的代碼所必需的。

當使用spawn方法時,子進程是通過創建一個“空”進程來創建的,即一個不從主進程繼承任何內容的進程,一個新的 Python 解釋器被啟動到該進程中。 這個新的解釋器必須重新讀取所有已經引用的源文件,以便在全局范圍內執行所有語句,以便在調用之前在新子進程的地址空間中重新創建全局變量、函數定義等,在您的情況下,函數tmp1.mul2 在新進程中, __name__不會'__main__' ,因此我們不會遞歸地重新執行創建這個新進程的代碼。

在全局范圍內創建新進程的代碼,也就是我們需要關注的范圍,實際上是在主腳本中,特別是result = tmp1.calculate(tmp1.mul2, inputs) 正是這段代碼需要在if __name__ == '__main__':塊中:

文件tmp2.py

if __name__ == '__main__':
    import tmp1

    inputs = [[1, 2, 3],
              [4, 5, 6],
              [7, 8, 9]]

    result = tmp1.calculate(tmp1.mul2, inputs)
    print(result)

我已將不需要在新子進程中執行的所有全局語句放入塊中,以便使用它可能需要執行的任何內容(即所有tmp2.py代碼)對其存儲進行初始化。

然后tmp1.py變為:

def mul2(x):
    return [a*2 for a in x]

def calculate(func, x):
    from multiprocessing import Pool

    r = []
    p = Pool(2)
    r.append(p.map(func, x))
    p.close()
    p.join()
    return r

以上打印:

[[[2, 4, 6], [8, 10, 12], [14, 16, 18]]]

這是一個列表的單個列表。 也許,你真的想要:

def mul2(x):
    return [a*2 for a in x]

def calculate(func, x):
    from multiprocessing import Pool

    p = Pool(2)
    r = p.map(func, x)
    p.close()
    p.join()
    return r

印刷品:

[[2, 4, 6], [8, 10, 12], [14, 16, 18]]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM