The Process and Pool classes

You can create a process that runs independently by subclassing multiprocessing.Process. You can extend the __init__ method to initialize resources, and you can write the portion of the code that will be executed in a subprocess by implementing the Process.run method. In the following code, we define a Process class that will wait for one second and print its assigned id:

    import multiprocessing 
import time

class Process(multiprocessing.Process):
def __init__(self, id):
super(Process, self).__init__()
self.id = id

def run(self):
time.sleep(1)
print("I'm the process with id: {}".format(self.id))

To spawn the process, we have to instantiate the Process class and call the Process.start method. Note that you don't directly call Process.run; the call to Process.start will create a new process that, in turn, will call the Process.run method. We can add the following lines at the end of the preceding snippet to create and start the new process:

    if __name__ == '__main__': 
p = Process(0)
p.start()

The instructions after Process.start will be executed immediately without waiting for the p process to finish. To wait for the task completion, you can use the Process.join method, as follows:

    if __name__ == '__main__': 
p = Process(0)
p.start()
p.join()

We can launch four different processes that will run parallely in the same way. In a serial program, the total required time will be four seconds. Since the execution is concurrent, the resulting wallclock time will be of one second. In the following code, we create four processes that will execute concurrently:

    if __name__ == '__main__': 
processes = Process(1), Process(2), Process(3), Process(4)
[p.start() for p in processes]

Note that the order of the execution for parallel processes is unpredictable and ultimately depends on how the OS schedules their execution. You can verify this behavior by executing the program multiple times; the order will likely be different between runs.

The multiprocessing module exposes a convenient interface that makes it easy to assign and distribute tasks to a set of processes that reside in the multiprocessing.Pool class.

The multiprocessing.Pool class spawns a set of processes--called workers--and lets us submit tasks through the apply/apply_async and map/map_async methods.

The Pool.map method applies a function to each element of a list and returns the list of results. Its usage is equivalent to the built-in (serial) map.

To use a parallel map, you should first initialize a multiprocessing.Pool object. It takes the number of workers as its first argument; if not provided, that number will be equal to the number of cores in the system. You can initialize a multiprocessing.Pool object in the following way:

    pool = multiprocessing.Pool() 
pool = multiprocessing.Pool(processes=4)

Let's see pool.map in action. If you have a function that computes the square of a number, you can map the function to the list by calling Pool.map and passing the function and the list of inputs as arguments, as follows:

    def square(x): 
return x * x

inputs = [0, 1, 2, 3, 4]
outputs = pool.map(square, inputs)

The Pool.map_async function is just like Pool.map but returns an AsyncResult object instead of the actual result. When we call  Pool.map, the execution of the main program is stopped until all the workers are finished processing the result. With map_async, the AsyncResult object is returned immediately without blocking the main program and the calculations are done in the background. We can then retrieve the result using the AsyncResult.get method at any time, as shown in the following lines:

    outputs_async = pool.map_async(square, inputs) 
outputs = outputs_async.get()

Pool.apply_async assigns a task consisting of a single function to one of the workers. It takes the function and its arguments and returns an AsyncResult object. We can obtain an effect similar to map using apply_async, as shown:

    results_async = [pool.apply_async(square, i) for i in range(100))] 
results = [r.get() for r in results_async]
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.142.36.146