Die Speicherauslastung wächst mit Pythons multiprocessing.pool

Hier ist das Programm:

#!/usr/bin/python

import multiprocessing

def dummy_func(r):
    pass

def worker():
    pass

if __name__ == '__main__':
    pool = multiprocessing.Pool(processes=16)
    for index in range(0,100000):
        pool.apply_async(worker, callback=dummy_func)

    # clean up
    pool.close()
    pool.join()

Fand ich die Speicherauslastung (beide und VIRT RES) wuchs bis close()/join(), gibt es eine Lösung, um loszuwerden dieses? Ich habe versucht, maxtasksperchild mit 2,7 aber es hat auch nicht geholfen.

Ich habe ein eher kompliziertes Programm, dass calles apply_async() ~6M Zeiten, und bei ~1,5 M Punkt ich hab schon 6G+ RES, um zu vermeiden, alle anderen Faktoren, die ich vereinfacht das Programm um die oben genannten version.

EDIT:

Stellte sich heraus diese version besser funktioniert, vielen Dank für jedermanns Eingang:

#!/usr/bin/python

import multiprocessing

ready_list = []
def dummy_func(index):
    global ready_list
    ready_list.append(index)

def worker(index):
    return index

if __name__ == '__main__':
    pool = multiprocessing.Pool(processes=16)
    result = {}
    for index in range(0,1000000):
        result[index] = (pool.apply_async(worker, (index,), callback=dummy_func))
        for ready in ready_list:
            result[ready].wait()
            del result[ready]
        ready_list = []

    # clean up
    pool.close()
    pool.join()

Ich nicht alle sperren gibt es, wie ich glaube, wichtigsten Prozess single-threaded (callback ist mehr oder weniger wie eine event-driven Sache pro docs gelesen habe).

Ich geändert v1 index-Bereich bis 1.000.000, gleichen als v2 und hat einige tests - es ist seltsam zu mir, v2 ist noch ~10% schneller als die v1 (33s vs 37s), vielleicht die v1 war dabei zu viele interne Liste Wartungsarbeiten. v2 ist definitiv ein Gewinner auf die Speichernutzung, es ging nie über 300M (VIRT) und 50M (RES), während v1 verwendet werden 370M/120M, das beste war 330M/85M. Alle zahlen waren nur 3~4 mal testen, nur als Referenz.

InformationsquelleAutor der Frage C.B. | 2013-08-24

Schreibe einen Kommentar