簡體   English   中英

OSError:[Errno 12]使用python多處理池時無法分配內存

[英]OSError: [Errno 12] Cannot allocate memory when using python multiprocessing Pool

我正在嘗試使用Python的multiprocessing將一個函數並行應用於5個交叉驗證集,並對不同的參數值重復該操作,如下所示:

import pandas as pd
import numpy as np
import multiprocessing as mp
from sklearn.model_selection import StratifiedKFold

#simulated datasets
X = pd.DataFrame(np.random.randint(2, size=(3348,868), dtype='int8'))
y = pd.Series(np.random.randint(2, size=3348, dtype='int64'))

#dummy function to apply
def _work(args):
    del(args)

for C in np.arange(0.0,2.0e-3,1.0e-6):
    splitter = StratifiedKFold(n_splits=5)
    with mp.Pool(processes=5) as pool:
        pool_results = \
            pool.map(
                func=_work,
                iterable=((C,X.iloc[train_index],X.iloc[test_index]) for train_index, test_index in splitter.split(X, y))
            )

但是在執行過程中,出現以下錯誤:

Traceback (most recent call last):
  File "mre.py", line 19, in <module>
    with mp.Pool(processes=5) as pool:
  File "/usr/lib/python3.5/multiprocessing/context.py", line 118, in Pool
    context=self.get_context())
  File "/usr/lib/python3.5/multiprocessing/pool.py", line 168, in __init__
    self._repopulate_pool()
  File "/usr/lib/python3.5/multiprocessing/pool.py", line 233, in _repopulate_pool
    w.start()
  File "/usr/lib/python3.5/multiprocessing/process.py", line 105, in start
    self._popen = self._Popen(self)
  File "/usr/lib/python3.5/multiprocessing/context.py", line 267, in _Popen
    return Popen(process_obj)
  File "/usr/lib/python3.5/multiprocessing/popen_fork.py", line 20, in __init__
    self._launch(process_obj)
  File "/usr/lib/python3.5/multiprocessing/popen_fork.py", line 67, in _launch
    self.pid = os.fork()
OSError: [Errno 12] Cannot allocate memory

我在具有32Gb內存的Ubuntu 16.04上運行此程序,並在執行過程中檢查htop ,它永遠不會超過18.5Gb,所以我不認為我的內存不足。
這絕對是由於使用splitter.split(X,y)的索引對數據幀進行了splitter.split(X,y)因為當我直接將數據幀傳遞給Pool對象時,不會引發任何錯誤。

我看到這個答案說這可能是由於創建了太多文件依賴關系所致,但是我不知道如何解決該問題,上下文管理器是否不應該幫助避免此類問題?

os.fork()復制一個進程,因此,如果您的使用量約為18 GB,並且想調用fork ,則需要另外18 GB。 兩次18是36 GB,遠遠超過32 GB。 盡管這種分析是(有意的)幼稚的(有些事情不會在fork上復制),但足以解釋這個問題。

解決方案是在需要較少內存復制時更早地創建池,或者在共享最大對象時更加努力。 或者,當然,向系統添加更多的內存(也許只是虛擬內存,即交換空間)。

暫無
暫無

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

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