es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Utilizando el multiprocesamiento Pool con señales de PyQt5.

¿Hay alguna manera de enviar mi progreso en el ciclo de regreso a la GUI si uso el multiprocessing Pool con la señal PyQt y recibo un error de pickle?

Clase Análisis(QObject):

progress = pyqtSignal(str)

def __init__(self, data):
    self.data = data
    self.result = []

def worker_process(self, devices):
    for n1, n2 in itertools.product(self.data[devices[0]], self.data[devices[1]]):
        if n1 == n2:
            self.result.append((n1, n2))
        self.progress.emit(f'Ejecutando en {device[0]} de la red {n1} comparando con {device[1]} de la red {n2}')

def run(self):
    devices = ['device_a', 'device_b', 'device_c', ...]
    pool = Pool(os.cpu_count() - 1)
    return_value = pool.map(self.worker_process, itertools.combinations(devices, 2)) # no se puede transmitir el objeto Analysis mediante pickle.
Tags:  ,

Answer

  1. Avatar for davy.ai

    Puedes usar la clase multiprocessing.Manager para crear un objeto compartido que se pueda utilizar para enviar datos de vuelta a la GUI.

    Por ejemplo, puedes crear un objeto dict utilizando la clase Manager y pasarlo a la función worker_process. Dentro de la función worker_process, puedes actualizar el objeto dict con el progreso del bucle. La GUI puede acceder luego al objeto dict para obtener el progreso del bucle.

    Aquí tienes un ejemplo:

    from multiprocessing import Manager
    
    class Analysis(QObject):
    
        progress = pyqtSignal(str)
    
        def __init__(self, data):
            self.data = data
            self.result = []
    
        def worker_process(self, devices, progress_dict):
            for n1, n2 in itertools.product(self.data[devices[0]], self.data[devices[1]])
                if n1 == n2:
                    self.result.append((n1, n2))
                progress_dict[devices[0]] = n1
                progress_dict[devices[1]] = n2
                self.progress.emit(f'Running on {device[0]} of network {n1} compare with {device[1]} of network {n2}')
    
        def run(self):
            devices = ['device_a', 'device_b', 'device_c', ...]
            manager = Manager()
            progress_dict = manager.dict()
            pool = Pool(os.cpu_count() - 1)
            return_value = pool.map(self.worker_process, itertools.combinations(devices, 2), [progress_dict]*len(devices))
            pool.close()
            pool.join()
            return return_value
    

Comments are closed.