Ho affrontato questo problema per una settimana e sta diventando piuttosto frustrante perché ogni volta che implemento un esempio più semplice ma simile di quello che devo fare, si scopre che il multiprocessing lo fonderà. Il modo in cui gestisce la memoria condivisa mi sconcerta perché è così limitato che può diventare inutile abbastanza rapidamente.Un modo migliore per condividere la memoria per la multiprocessing in Python?
Quindi la descrizione di base del mio problema è che ho bisogno di creare un processo che viene passato in alcuni parametri per aprire un'immagine e creare circa 20K patch di dimensioni 60x40. Queste patch vengono salvate in un elenco 2 alla volta e devono essere restituite al thread principale per essere quindi elaborate di nuovo da altri due processi simultanei eseguiti sulla GPU.
Il processo, il flusso di lavoro e tutto ciò di cui ci si preoccupa maggiormente, ciò di cui ho bisogno ora è che la parte che doveva essere la più semplice si sta rivelando la più difficile. Non sono stato in grado di salvare e ottenere la lista con patch 20K sul thread principale.
Il primo problema era perché stavo salvando queste patch come immagini PIL. Ho poi scoperto che tutti i dati aggiunti a un oggetto Queue devono essere decapitati. Secondo problema, ho quindi convertito le patch in un array di 60x40 ciascuna e le ho salvate in un elenco. E ora che ancora non funziona? Apparentemente le code hanno una quantità limitata di dati che possono essere salvati diversamente quando chiamate queue_obj.get() il programma si blocca.
Ho provato molte altre cose e ogni nuova cosa che provo non funziona, quindi mi piacerebbe sapere se qualcuno ha altre raccomandazioni di una libreria che posso usare per condividere oggetti senza tutto il fuzz?
Ecco un esempio di implementazione di tipo di ciò che sto guardando. Tieni presente che funziona perfettamente, ma la piena implementazione no. E ho il codice di stampare i messaggi informativi per vedere che i dati salvati hanno la stessa forma e tutto, ma per qualche motivo non funziona. Nell'implementazione completa il processo indipendente viene completato correttamente ma si blocca su q.get().
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()
Intendi interrompere un'immagine in molte patch (tile) e salvarle come elenco di array e che desideri utilizzare più thread per accelerare questo processo? – user3667217
Ogni immagine è suddivisa in molte patch e salvata come un singolo elenco di 20K patch per immagine. Questa parte è tutto fatto in un unico processo, non ho bisogno di dividere i dati, ho solo bisogno di ottenere quella lista specifica creata sul thread principale. Quindi i processi multipli creerebbero più elenchi di patch da 20K ciascuno e li rimandano al programma principale per elaborare ora 2 di questi elenchi alla volta sulle mie 2 GPU. – alfredox