2016-04-13 6 views
3

Ich versuche, einen Algorithmus zu beschleunigen, der eine riesige Matrix verwendet. Ich habe es parallelisiert, um in Reihen zu arbeiten, und stelle die Datenmatrix in den gemeinsamen Speicher, damit das System nicht verstopft wird. Anstatt jedoch so zu arbeiten, wie ich es mir erhofft hatte, wirft es jetzt einen seltsamen Fehler in Bezug auf Dateien auf, was ich nicht verstehe, da ich nicht einmal Dateien in dem Ding öffne.Python-Multiprocessing beansprucht zu viele offene Dateien, wenn keine Dateien überhaupt geöffnet sind

Mock-up von ungefähr, was im eigentlichen Programm vor sich geht, mit der 1000-Iteration, um repräsentativ zu sein, was auch im Algorithmus passiert.

import multiprocessing 
import ctypes 
import numpy as np 

shared_array_base = multiprocessing.Array(ctypes.c_double, 10*10) 
shared_array = np.ctypeslib.as_array(shared_array_base.get_obj()) 
shared_array = shared_array.reshape(10, 10) 

def my_func(i, shared_array): 
    shared_array[i,:] = i 

def pool_init(_shared_array, _constans): 
    global shared_array, constans 
    shared_array = _shared_array 
    constans = _constans 

def pool_my_func(i): 
    my_func(i, shared_array) 

if __name__ == '__main__': 
    for i in np.arange(1000): 
     pool = multiprocessing.Pool(8, pool_init, (shared_array, 4)) 
     pool.map(pool_my_func, range(10)) 
    print(shared_array) 

Und das wirft diesen Fehler (ich bin auf OSX):

Traceback (most recent call last): 
    File "weird.py", line 24, in <module> 
    pool = multiprocessing.Pool(8, pool_init, (shared_array, 4)) 
    File "//anaconda/lib/python3.4/multiprocessing/context.py", line 118, in Pool 
    context=self.get_context()) 
    File "//anaconda/lib/python3.4/multiprocessing/pool.py", line 168, in __init__ 
    self._repopulate_pool() 
    File "//anaconda/lib/python3.4/multiprocessing/pool.py", line 233, in _repopulate_pool 
    w.start() 
    File "//anaconda/lib/python3.4/multiprocessing/process.py", line 105, in start 
    self._popen = self._Popen(self) 
    File "//anaconda/lib/python3.4/multiprocessing/context.py", line 267, in _Popen 
    return Popen(process_obj) 
    File "//anaconda/lib/python3.4/multiprocessing/popen_fork.py", line 21, in __init__ 
    self._launch(process_obj) 
    File "//anaconda/lib/python3.4/multiprocessing/popen_fork.py", line 69, in _launch 
    parent_r, child_w = os.pipe() 
OSError: [Errno 24] Too many open files 

ich ziemlich ratlos bin. Ich öffne nicht einmal Dateien hier. Alles, was ich tun möchte, ist, die shared_array an die einzelnen Prozesse in einer Weise zu übergeben, die den Systemspeicher nicht verstopft, ich muss es nicht einmal innerhalb des parallelisierten Prozesses ändern, wenn dies irgendetwas hilft.

Auch im Fall es wichtig ist, die genauen Fehler durch den richtigen Code geworfen selbst sind ein wenig anders:

Traceback (most recent call last): 
    File "tcap.py", line 206, in <module> 
    File "tcap.py", line 202, in main 
    File "tcap.py", line 181, in tcap_cluster 
    File "tcap.py", line 133, in ap_step 
    File "//anaconda/lib/python3.4/multiprocessing/context.py", line 118, in Pool 
    File "//anaconda/lib/python3.4/multiprocessing/pool.py", line 168, in __init__ 
    File "//anaconda/lib/python3.4/multiprocessing/pool.py", line 233, in _repopulate_pool 
    File "//anaconda/lib/python3.4/multiprocessing/process.py", line 105, in start 
    File "//anaconda/lib/python3.4/multiprocessing/context.py", line 267, in _Popen 
    File "//anaconda/lib/python3.4/multiprocessing/popen_fork.py", line 21, in __init__ 
    File "//anaconda/lib/python3.4/multiprocessing/popen_fork.py", line 69, in _launch 
OSError: [Errno 24] Too many open files 

Also ja, ich habe keine Ahnung, wie es weitergeht. Jede Hilfe wäre willkommen. Danke im Voraus!

Antwort

6

Sie versuchen, Prozesspools zu erstellen, die (aus irgendeinem Grund) nicht zurückgefordert werden; Diese haben alle verfügbaren Dateideskriptoren in Ihrem Hauptprozess für die Pipes verbraucht, die für die Kommunikation zwischen dem Hauptprozess und seinen untergeordneten Elementen verwendet werden.

Vielleicht möchten Sie verwenden möchten:

pool = multiprocessing.Pool(8, pool_init, (shared_array, 4)) 
for _ in range(1000): 
    pool.map(pool_my_func, range(10)) 
+0

Das ist es gelöst, danke! –

Verwandte Themen