Can someone point out what is wrong with this code snippet. It does not give any results .
import multiprocessing
results = []
def log_results(result):
results.append(result)
def multiply(x, y):
print(f"Gets here for process name {multiprocessing.current_process().name()}")
return x * y
if __name__ == "__main__":
pool = multiprocessing.Pool()
numbers = [(1,1), (2,2), (3,3)]
for x, y in numbers:
print (f"Checking x {x} and y {y}")
pool.apply_async(multiply, (x, y), callback=log_results)
pool.close()
pool.join()
print(results)
results is an empty list which should not be in this case right ? I have used apply_async and map_async . Both do not give the right output. Can someone please help me here
The Pool class in multiprocessing can handle an enormous number of processes. It allows you to run multiple jobs per process (due to its ability to queue the jobs). The memory is allocated only to the executing processes, unlike the Process class, which allocates memory to all the processes.
Pool . It creates multiple Python processes in the background and spreads out your computations for you across multiple CPU cores so that they all happen in parallel without you needing to do anything.
CPU time gets rationed out between the threads. Multiprocessing is for times when you really do want more than one thing to be done at any given time. Suppose your application needs to connect to 6 databases and perform a complex matrix transformation on each dataset.
Multiprocess is a Python package that supports spawning processing tasks using an API similar to the Python threading module. In addition, the multiprocessing package supports concurrency in both local and remote types, allowing you to bypass the global interpreter lock that comes with threading.
Edit: You made an edit to your code so now my answer below is out of date. The only two things I think need doing are:
error_callback
because I still think you need to ensure that the pool as written does not fail silently by default.multiprocessing.current_process().name()
as multiprocessing.current_process().name
.So:
import multiprocessing
results = []
def log_results(result):
results.append(result)
def log_e(e):
print(e)
def multiply(x, y):
print(f"Gets here for process name {multiprocessing.current_process().name}")
return x * y
pool = multiprocessing.Pool()
numbers = [(1,1), (2,2), (3,3)]
for x, y in numbers:
print (f"Checking x {x} and y {y}")
pool.apply_async(multiply, (x, y), callback=log_results,
error_callback=log_e)
pool.close()
pool.join()
print(results)
Old answer
This drove me crazy for a moment but then it made sense.
If I run it with multiply
changed like this:
def multiply(nums):
print("print")
return nums[0] * nums[1]
It runs fine. You said in the comments "I do not think the function multiply
is called in the first place." This is because there is a callback
specified but no error_callback
specified. The result of omitting an error callback is that your script is failing silently.
You could check this with:
import multiprocessing
results = []
def log_results(result):
print(result)
def log_e(e):
print(e)
def multiply(x, y):
print(f"Gets here for process name {multiprocessing.current_process().name()}")
return x * y
pool = multiprocessing.Pool()
numbers = [[1,1], [2,2], [3,3]]
mapResult = pool.map_async(multiply, numbers, callback=log_results,
error_callback=log_e)
pool.close()
pool.join()
Which gives:
multiply() missing 1 required positional argument: 'y'
And with multiply
like so:
def multiply(nums):
return nums[0] * nums[1]
It then returns [1, 4, 9]
PS I am running Python 3.6.7
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With