Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using multiprocessing pool in Python

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

like image 984
Subhayan Bhattacharya Avatar asked Apr 05 '19 12:04

Subhayan Bhattacharya


People also ask

How does multiprocessing pool work Python?

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.

What is Pool () in Python?

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.

When should I use multiprocessing in Python?

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.

Does multiprocessing work in Python?

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.


1 Answers

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:

  1. add an error_callback because I still think you need to ensure that the pool as written does not fail silently by default.
  2. rewrite 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

like image 143
Charles Landau Avatar answered Sep 18 '22 20:09

Charles Landau