So I thought I'd finally post; what is the proper way to manage Process workers? I've tried to use a Pool, but I noticed I could not get the return value of each completed process. I tried to use a callback but that didn't work as expected either. Should I just be managing them myself with active_children ()?
My Pool code:
from multiprocessing import *
import time
import random
SOME_LIST = []
def myfunc():
a = random.randint(0,3)
time.sleep(a)
return a
def cb(retval):
SOME_LIST.append(retval)
print("Starting...")
p = Pool(processes=8)
p.apply_async(myfunc, callback=cb)
p.close()
p.join()
print("Stopping...")
print(SOME_LIST)
I expect a list of values; but all I get is the last item in the worker job to complete:
$ python multi.py
Starting...
Stopping...
[3]
Note: The answer should not use threading module; here is the reason why:
In CPython, due to the Global Interpreter Lock, only one thread can execute Python code at once (even though certain performance-oriented libraries might overcome this limitation). If you want your application to make better use of the computational resources of multi-core machines, you are advised to use multiprocessing.
Poolis the correct way. You should be able to get the return value of each completed workerProcess, too :return_value = pool.apply(func, args=(arg1, arg2). Can you share the code you're trying to use that isn't working?return_value = pool.apply(func). Wherefuncisdef func(): return 12345.return_valuewill be assigned to the12345returned byfunc.apply_asynconce, which means you're just callingmyfunca single time in one of the worker processes. What are you expecting to happen?for _ in range(pool._processes): pool.apply_async(myfunc, callback=cb). Or, if you makemyfunctake a single argument (which you could ignore), you could do:SOME_LIST = pool.map(myfunc, range(pool._processes))