¿Cómo puedo obtener el valor de retorno de una función pasada al proceso de multiprocesamiento?

Resuelto Louis Thibault asked hace 12 años • 14 respuestas

En el código de ejemplo siguiente, me gustaría obtener el valor de retorno de la función worker. ¿Cómo puedo hacer esto? ¿Dónde se almacena este valor?

Código de ejemplo:

import multiprocessing

def worker(procnum):
    '''worker function'''
    print str(procnum) + ' represent!'
    return procnum


if __name__ == '__main__':
    jobs = []
    for i in range(5):
        p = multiprocessing.Process(target=worker, args=(i,))
        jobs.append(p)
        p.start()

    for proc in jobs:
        proc.join()
    print jobs

Producción:

0 represent!
1 represent!
2 represent!
3 represent!
4 represent!
[<Process(Process-1, stopped)>, <Process(Process-2, stopped)>, <Process(Process-3, stopped)>, <Process(Process-4, stopped)>, <Process(Process-5, stopped)>]

Parece que no puedo encontrar el atributo relevante en los objetos almacenados en jobs.

Louis Thibault avatar May 02 '12 20:05 Louis Thibault
Aceptado

Utilice una variable compartida para comunicarse. Por ejemplo, así,

Código de ejemplo:

import multiprocessing


def worker(procnum, return_dict):
    """worker function"""
    print(str(procnum) + " represent!")
    return_dict[procnum] = procnum


if __name__ == "__main__":
    manager = multiprocessing.Manager()
    return_dict = manager.dict()
    jobs = []
    for i in range(5):
        p = multiprocessing.Process(target=worker, args=(i, return_dict))
        jobs.append(p)
        p.start()

    for proc in jobs:
        proc.join()
    print(return_dict.values())

Producción:

0 represent!
1 represent!
3 represent!
2 represent!
4 represent!
[0, 1, 3, 2, 4]
vartec avatar May 02 '2012 13:05 vartec

Creo que el enfoque sugerido por sega_sai es el mejor. Pero realmente necesita un ejemplo de código, así que aquí va:

import multiprocessing
from os import getpid

def worker(procnum):
    print('I am number %d in process %d' % (procnum, getpid()))
    return getpid()

if __name__ == '__main__':
    pool = multiprocessing.Pool(processes = 3)
    print(pool.map(worker, range(5)))

Que imprimirá los valores de retorno:

I am number 0 in process 19139
I am number 1 in process 19138
I am number 2 in process 19140
I am number 3 in process 19139
I am number 4 in process 19140
[19139, 19138, 19140, 19139, 19140]

Si está familiarizado con mapPython 2 integrado, esto no debería ser demasiado difícil. De lo contrario, eche un vistazo al enlace de sega_Sai .

Tenga en cuenta lo poco que se necesita código. (Observe también cómo se reutilizan los procesos).

Mark avatar Mar 01 '2015 21:03 Mark

Para cualquier otra persona que esté buscando cómo obtener un valor de un Processuso Queue:

import multiprocessing

ret = {'foo': False}

def worker(queue):
    ret = queue.get()
    ret['foo'] = True
    queue.put(ret)

if __name__ == '__main__':
    queue = multiprocessing.Queue()
    queue.put(ret)
    p = multiprocessing.Process(target=worker, args=(queue,))
    p.start()
    p.join()
    print(queue.get())  # Prints {"foo": True}

Tenga en cuenta que en Windows o Jupyter Notebook, multithreadingdebe guardarlo como un archivo y ejecutarlo. Si lo haces en un símbolo del sistema verás un error como este:

 AttributeError: Can't get attribute 'worker' on <module '__main__' (built-in)>
Matthew Moisen avatar Jun 09 '2016 21:06 Matthew Moisen