![](/img/trans.png)
[英]How to pass argument in multiprocessing function and how to use multiprocessing list?
[英]How to use multiprocessing in function?
我想在“ a.py”中定義一個函數,該函數使用多處理進行並行化,然后將其作為庫函數導入“ b.py”中。 例如,在“ a.py”中:
import multiprocessing as mp, queue
def MPWorker(input, i):
input.put(i)
def MPTest(MaxMPNum):
jobs = []
BatchResult = queue.Queue()
for i in range(MaxMPNum):
p = mp.Process(target=MPWorker, args=(BatchResult, i + 1))
p.start()
print("this is", i)
jobs.append(p)
for i in range(MaxMPNum):
print("getting", i)
result = BatchResult.get()
print(result)
然后在“ b.py”中:
import a
a.MPTest(10)
但是,它將無法正常工作,我將始終收到錯誤:_pickle.PicklingError:無法進行腌制:_thread上的屬性查找鎖定失敗。 那么,是否有可能以這種方式使用python的多處理功能,或者我錯過了任何東西?
整個追溯,略做編輯(Python 3.x,Windows):
Traceback (most recent call last):
File "F:/b.py", line 72, in <module>
a.MPTest(5)
File "F:\a.py", line 566, in MPTest
p.start()
File "C:\Python34\lib\multiprocessing\process.py", line 105, in start
self._popen = self._Popen(self)
File "C:\Python34\lib\multiprocessing\context.py", line 212, in _Popen
return _default_context.get_context().Process._Popen(process_obj)
File "C:\Python34\lib\multiprocessing\context.py", line 313, in _Popen
return Popen(process_obj)
File "C:\Python34\lib\multiprocessing\popen_spawn_win32.py", line 66, in __init__
reduction.dump(process_obj, to_child)
File "C:\Python34\lib\multiprocessing\reduction.py", line 59, in dump
ForkingPickler(file, protocol).dump(obj)
_pickle.PicklingError: Can't pickle <class '_thread.lock'>: attribute lookup lock on _thread failed
問題在於您使用的是queue.Queue
,它僅在同一進程中的線程之間起作用,而不是multiprocessing.Queue
,其在進程之間是起作用的。
根據您的平台和使用方式,這將以不同的方式失敗。 在您的情況下,因為您正在嘗試將隊列作為參數傳遞給Process
構造函數,並且您在Windows上,則會遇到最棒的錯誤:嘗試對隊列本身進行酸洗,然后失敗。*在Unix上,您實際上可以成功地將隊列傳遞給子進程,但是當您使用它時,它可能會丟失大多數值(OS X)或死鎖(大多數其他系統)。
正如文檔所解釋的, multiprocessing.Queue
“是queue.Queue
的近乎克隆”,除了它是“線程和進程安全的”,而不僅僅是線程安全的。
如果您認為您正在使用multiprocessing.Queue
,那么您的錯誤就在此行中:
import multiprocessing as mp, queue
這不會同時將multiprocessing
作為mp
和queue
導入,而是將multiprocessing
作為mp
導入,並將queue
本身作為導入。 有關詳細信息,請參見import
參考。
它對人類是不明確的(即使它對解析器而言不是不明確的事實)是在Python中不鼓勵多次導入語句的原因之一。 例如, PEP 8說“導入通常應該放在單獨的行上”。
*如果在您對其進行腌制時隊列本身引發了異常,而不是依賴於它使用一些不可腌制的線程同步對象這一事實可能會更好,因為對_thread.lock
進行腌制並不是完全由腌制queue.Queue
引起的queue.Queue
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.