Ich habe dieses Problem jetzt seit einer Woche angepackt und es ist ziemlich frustrierend geworden, denn jedes Mal, wenn ich ein einfacheres, aber ähnliches Beispiel verwende, wird es Multiprocessing sein. Die Art und Weise, wie es Shared Memory behandelt, verwirrte mich, weil es so begrenzt ist, dass es ziemlich schnell unbrauchbar werden kann.Bessere Möglichkeit, Speicher für Multiprocessing in Python zu teilen?
Also die grundlegende Beschreibung meines Problems ist, dass ich einen Prozess erstellen muss, der in einigen Parametern übergeben wird, um ein Bild zu öffnen und ca. 20K Patches der Größe 60x40 zu erstellen. Diese Patches werden jeweils in einer Liste 2 gespeichert und müssen an den Hauptthread zurückgegeben werden, um dann von zwei anderen gleichzeitigen Prozessen, die auf der GPU ausgeführt werden, erneut verarbeitet zu werden.
Der Prozess und der Workflow und alles, was meistens erledigt wird, was ich jetzt brauche, ist der Teil, der am einfachsten sein sollte, erweist sich als der schwierigste. Ich konnte nicht speichern und die Liste mit 20K Patches zurück zum Hauptthread bekommen.
Das erste Problem war, weil ich diese Patches als PIL-Bilder gespeichert habe. Ich habe dann herausgefunden, dass alle Daten, die zu einem Queue-Objekt hinzugefügt werden, gebeizt werden müssen. Das zweite Problem war, dass ich dann die Patches in ein Array von je 60x40 konvertiert und in einer Liste gespeichert habe. Und das geht jetzt immer noch nicht? Anscheinend haben Warteschlangen eine begrenzte Menge an Daten, die sie sonst speichern können, wenn Sie queue_obj.get() aufrufen, hängt das Programm.
Ich habe viele andere Dinge ausprobiert, und jede neue Sache, die ich versuche, funktioniert nicht, also würde ich gerne wissen, ob jemand andere Empfehlungen einer Bibliothek hat, die ich verwenden kann, um Objekte ohne all den Fuzz zu teilen?
Hier ist eine Beispiel-Implementierung der Art von was ich betrachte. Denken Sie daran, das funktioniert vollkommen in Ordnung, aber die vollständige Implementierung nicht. Und ich habe den Code, um Informationsnachrichten zu drucken, um zu sehen, dass die gespeicherten Daten die exakt gleiche Form und alles haben, aber aus irgendeinem Grund funktioniert es nicht. In der vollständigen Implementierung wird der unabhängige Prozess erfolgreich abgeschlossen, jedoch bei q.get() eingefroren.
from PIL import Image
from multiprocessing import Queue, Process
import StringIO
import numpy
img = Image.open("/path/to/image.jpg")
q = Queue()
q2 = Queue()
#
#
# MAX Individual Queue limit for 60x40 images in BW is 31,466.
# Multiple individual Queues can be filled to the max limit of 31,466.
# A single Queue can only take up to 31,466, even if split up in different puts.
def rz(patch, qn1, qn2):
totalPatchCount = 20000
channels = 1
patch = patch.resize((60,40), Image.ANTIALIAS)
patch = patch.convert('L')
# ImgArray = numpy.asarray(im, dtype=numpy.float32)
list_im_arr = []
# ----Create a 4D Array
# returnImageArray = numpy.zeros(shape=(totalPatchCount, channels, 40, 60))
imgArray = numpy.asarray(patch, dtype=numpy.float32)
imgArray = imgArray[numpy.newaxis, ...]
# ----End 4D array
# list_im_arr2 = []
for i in xrange(totalPatchCount):
# returnImageArray[i] = imgArray
list_im_arr.append(imgArray)
qn1.put(list_im_arr)
qn1.cancel_join_thread()
# qn2.cancel_join_thread()
print "PROGRAM Done"
# rz(img,q,q2)
# l = q.get()
#
p = Process(target=rz,args=(img, q, q2,))
p.start()
p.join()
#
# # l = []
# # for i in xrange(1000): l.append(q.get())
#
imdata = q.get()
Möchten Sie ein Bild in viele Patches (Kacheln) aufteilen und sie als Liste von Arrays speichern und mehrere Threads verwenden, um diesen Prozess zu beschleunigen? – user3667217
Jedes Bild wird in viele Patches aufgeteilt und als eine einzige Liste von 20K-Patches pro Bild gespeichert. Dieser Teil ist alles in einem Prozess, ich brauche die Daten nicht zu teilen, ich muss nur diese spezifische Liste zurück zum Haupt-Thread erstellt bekommen. Also würden die mehreren Prozesse mehrere Listen von jeweils 20K Patches erstellen und sie an das Hauptprogramm zurücksenden, um nun zwei dieser Listen gleichzeitig auf meinen zwei GPUs zu verarbeiten. – alfredox