2

I am doing several process togethere. Each of the proccess returns some results. How would I collect those results from those process.

 task_1 = Process(target=do_this_task,args=(para_1,para_2))
 task_2 = Process(target=do_this_task,args=(para_1,para_2))

do_this_task returns some results. I would like to collect those results and save them in some variable.

thetna
  • 6,903
  • 26
  • 79
  • 113
  • Use `apply_async` from the `multiprocessing` module, as described [here](http://docs.python.org/2/library/multiprocessing.html#using-a-pool-of-workers) – mtadd Jul 29 '13 at 15:35

3 Answers3

1

So right now I would suggest you should use the python multiprocessing module's Pool as it handles quite a bit for you. Could you elaborate what you're doing and why you want to use what I assume to be multiprocessing.Process directly?

If you still want to use multiprocessing.Process directly you should use a Queue to get the return values.

example given in the docs:

"

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print q.get()    # prints "[42, None, 'hello']"
    p.join()

"-Multiprocessing Docs

So processes are things that usually run in the background to do something in general, if you do multiprocessing with them you need to 'throw around' the data since processes don't have shared memory like threads - so that's why you use the Queue - it does it for you. Another thing you can do is pipes, and conveniently they give an example for that as well :). "

from multiprocessing import Process, Pipe

def f(conn):
    conn.send([42, None, 'hello'])
    conn.close()

if __name__ == '__main__':
    parent_conn, child_conn = Pipe()
    p = Process(target=f, args=(child_conn,))
    p.start()
    print parent_conn.recv()   # prints "[42, None, 'hello']"
    p.join()

" -Multiprocessing Docs

what this does is manually use pipes to throw around the finished results to the 'parent process' in this case.

Also sometimes I find cases which multiprocessing cannot pickle well so I use this great answer (or my modified specialized variants of) by mrule that he posts here:

"

from multiprocessing import Process, Pipe
from itertools import izip

def spawn(f):
    def fun(pipe,x):
        pipe.send(f(x))
        pipe.close()
    return fun

def parmap(f,X):
    pipe=[Pipe() for x in X]
    proc=[Process(target=spawn(f),args=(c,x)) for x,(p,c) in izip(X,pipe)]
    [p.start() for p in proc]
    [p.join() for p in proc]
    return [p.recv() for (p,c) in pipe]

if __name__ == '__main__':
    print parmap(lambda x:x**x,range(1,5))

"

you should be warned however that this takes over control manually of the processes so certain things can leave 'dead' processes lying around - which is not a good thing, an example being unexpected signals - this is an example of using pipes for multi-processing though :).

If those commands are not in python, e.g. you want to run ls then you might be better served by using subprocess, as os.system isn't a good thing to use anymore necessarily as it is now considered that subprocess is an easier-to-use and more flexible tool, a small discussion is presented here.

Community
  • 1
  • 1
Eiyrioü von Kauyf
  • 4,481
  • 7
  • 32
  • 41
1

You can do something like this with multiprocessing

from multiprocessing import Pool

mydict = {}
with Pool(processes=5) as pool:
        task_1 = pool.apply_async(do_this_task,args=(para_1,para_2))
        task_2 = pool.apply_async(do_this_task,args=(para_1,para_2))
        mydict.update({"task_1": task_1.get(), "task_2":task_2.get()})
print(mydict)

or if you would like to try multithreading with concurrent.futures then take a look at this answer.

Rakesh Sharma
  • 608
  • 6
  • 9
0

If the processes are external scripts then try using the subprocess module. However, your code suggests you want to run functions in parallel. For this, try the multiprocessing module. Some code from this answer for specific details of using multiprocessing:

def foo(bar, baz):
    print 'hello {0}'.format(bar)
    return 'foo' + baz

from multiprocessing.pool import ThreadPool
pool = ThreadPool(processes=1)

async_result = pool.apply_async(foo, ('world', 'foo')) # tuple of args for foo

# do some other stuff in the other processes

return_val = async_result.get()  # get the return value from your function.
Community
  • 1
  • 1
rlms
  • 10,650
  • 8
  • 44
  • 61