Ich möchte ein Numpy-Array im gemeinsam genutzten Speicher zur Verwendung mit dem Multiprocessing-Modul verwenden. Die Schwierigkeit besteht darin, es wie ein Numpy-Array zu verwenden und nicht nur als ctypes-Array.
from multiprocessing import Process, Array
import scipy
def f(a):
a[0] = -a[0]
if __name__ == '__main__':
# Create the array
N = int(10)
unshared_arr = scipy.rand(N)
arr = Array('d', unshared_arr)
print "Originally, the first two elements of arr = %s"%(arr[:2])
# Create, start, and finish the child processes
p = Process(target=f, args=(arr,))
p.start()
p.join()
# Printing out the changed values
print "Now, the first two elements of arr = %s"%arr[:2]
Dies erzeugt eine Ausgabe wie:
Originally, the first two elements of arr = [0.3518653236697369, 0.517794725524976]
Now, the first two elements of arr = [-0.3518653236697369, 0.517794725524976]
Auf das Array kann auf ctypes Weise zugegriffen werden, z arr[i]
. B. macht es Sinn. Es ist jedoch kein Numpy-Array, und ich kann keine Operationen wie -1*arr
oder ausführen arr.sum()
. Ich nehme an, eine Lösung wäre, das ctypes-Array in ein numpy-Array umzuwandeln. Ich glaube jedoch nicht (dass ich nicht in der Lage bin, diese Arbeit zu machen), dass sie nicht mehr geteilt wird.
Es scheint eine Standardlösung für ein allgemeines Problem zu geben.
python
numpy
multiprocessing
shared
Ian Langmore
quelle
quelle
subprocess
eher nach alsmultiprocessing
.Antworten:
Hinzufügen zu den Antworten von @ unutbu (nicht mehr verfügbar) und @Henry Gomersall. Sie können
shared_arr.get_lock()
den Zugriff bei Bedarf synchronisieren:Beispiel
Wenn Sie keinen synchronisierten Zugriff benötigen oder eigene Sperren erstellen, ist dies nicht erforderlich
mp.Array()
. Sie könntenmp.sharedctypes.RawArray
in diesem Fall verwenden.quelle
count
an übergebennumpy.frombuffer()
. Sie können versuchen, dies auf einer niedrigeren Ebene zu tun, indem Sie ein RawArray-Analogon (oder möglicherweise nach einer vorhandenen Bibliothek suchen) verwendenmmap
oder etwasposix_ipc
direktes implementieren, um eine Größenänderung zu implementieren (möglicherweise das Kopieren während der Größenänderung). Oder wenn es Ihre Aufgabe erlaubt: Kopieren Sie Daten in Teilen (wenn Sie nicht alle auf einmal benötigen). "So ändern Sie die Größe eines gemeinsam genutzten Speichers" ist eine gute separate Frage.Pool()
die Anzahl der Prozesse (die Anzahl der verfügbaren CPU-Kerne wird standardmäßig verwendet).M
ist die Häufigkeit, mit der dief()
Funktion aufgerufen wird.Dem
Array
Objekt ist eineget_obj()
Methode zugeordnet, die das Array ctypes zurückgibt, das eine Pufferschnittstelle darstellt. Ich denke, das Folgende sollte funktionieren ...Beim Ausführen wird das erste Element von
a
jetzt 10.0 gedruckt , wobeia
und angezeigt werdenb
sind nur zwei Ansichten in den gleichen Speicher.Um noch es um sicherzustellen , dass Multi - Prozessor sicher, ich glaube , Sie werden die benutzen müssen
acquire
undrelease
Methoden , die auf dem existierenArray
Objekt,a
und seine in Schloss gebaut , um sicherzustellen , es ist alles sicher zugegriffen wird (obwohl ich kein Experte bin auf der Multiprozessormodul).quelle
mp.Array
.Obwohl die bereits gegebenen Antworten gut sind, gibt es eine viel einfachere Lösung für dieses Problem, vorausgesetzt, zwei Bedingungen sind erfüllt:
In diesem Fall müssen Sie nicht damit herumspielen, Variablen explizit gemeinsam zu nutzen, da die untergeordneten Prozesse mit einem Fork erstellt werden. Ein gegabeltes Kind teilt automatisch den Speicherplatz des Elternteils. Im Kontext der Python-Mehrfachverarbeitung bedeutet dies, dass alle Variablen auf Modulebene gemeinsam genutzt werden. Beachten Sie, dass dies nicht für Argumente gilt, die Sie explizit an Ihre untergeordneten Prozesse oder an die Funktionen übergeben, die Sie für a aufrufen
multiprocessing.Pool
oder so .Ein einfaches Beispiel:
quelle
Ich habe ein kleines Python-Modul geschrieben, das POSIX Shared Memory verwendet, um Numpy-Arrays zwischen Python-Interpreten zu teilen. Vielleicht finden Sie es praktisch.
https://pypi.python.org/pypi/SharedArray
So funktioniert das:
quelle
Sie können das
sharedmem
Modul verwenden: https://bitbucket.org/cleemesser/numpy-sharedmemHier ist Ihr ursprünglicher Code, diesmal unter Verwendung eines gemeinsam genutzten Speichers, der sich wie ein NumPy-Array verhält (beachten Sie die zusätzliche letzte Anweisung, die eine NumPy-
sum()
Funktion aufruft ):quelle