0% found this document useful (0 votes)
17 views

Lab4 Multiprocessing in Python

Uploaded by

superfunstar25
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
17 views

Lab4 Multiprocessing in Python

Uploaded by

superfunstar25
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 5

Multiprocessing in Python

Introduction

Python's multiprocessing module allows you to create processes that run concurrently, taking
advantage of multiple CPU cores. This is particularly useful for tasks that are CPU-bound, as it
can significantly speed up processing time by utilizing all available cores.

Prerequisites

• Python 3.x installed on your system.


• Basic knowledge of Python programming (functions, classes, and basic syntax).
• An IDE or code editor (e.g., PyCharm).

Lab Objectives

1. Understand the concept of multiprocessing.


2. Learn how to create processes using Python's multiprocessing module.
3. Implement common multiprocessing techniques such as Process, Pool, Queue, and
Lock.
4. Learn how to share data between processes and synchronize them.

1. Basics of Multiprocessing

1.1 Understanding Processes

• A process is an independent program running in its own memory space.


• Python's multiprocessing module allows us to spawn multiple processes.

1.2 Importing the Module

import multiprocessing

2. Creating a Process

2.1 Using Process Class

The Process class is used to create a new process.


Example: Creating a Process

import multiprocessing

def worker_function():
print("Hello from a new process!")

if __name__ == "__main__":
process = multiprocessing.Process(target=worker_function)
process.start() # Starts the process
process.join() # Waits for the process to complete
print("Main process complete.")

Explanation:

• target specifies the function that the new process will run.
• start() launches the process.
• join() ensures that the main process waits until the new process finishes.

3. Using Pool for Process Pooling

3.1 Using Pool Class

Pool allows you to manage multiple worker processes and distribute tasks among them.

Example: Using Pool

import multiprocessing

def square(n):
return n * n

if __name__ == "__main__":
with multiprocessing.Pool(processes=4) as pool:
numbers = [1, 2, 3, 4, 5]
results = pool.map(square, numbers)
print("Squares:", results)

Explanation:

• Pool(processes=4) creates a pool of 4 processes.


• map() applies the function square to each element in numbers.
• The with statement automatically handles closing the pool.

4. Inter-Process Communication

4.1 Using Queue for Data Sharing

Queue is a thread- and process-safe FIFO queue for communication between processes.
Example: Using Queue

import multiprocessing

def producer(queue):
for i in range(5):
queue.put(i)
print(f"Produced: {i}")

def consumer(queue):
while not queue.empty():
item = queue.get()
print(f"Consumed: {item}")

if __name__ == "__main__":
queue = multiprocessing.Queue()
p1 = multiprocessing.Process(target=producer, args=(queue,))
p2 = multiprocessing.Process(target=consumer, args=(queue,))

p1.start()
p1.join() # Ensure the producer finishes before starting the consumer.
p2.start()
p2.join()

Explanation:

• Queue is used to store items produced by one process and consumed by another.
• put() adds an item to the queue, while get() retrieves it.

5. Synchronization between Processes

5.1 Using Lock for Synchronization

Lock can prevent race conditions when multiple processes try to access shared resources.

Example: Using Lock

import multiprocessing

def increment(counter, lock):


for _ in range(1000):
with lock:
counter.value += 1

if __name__ == "__main__":
lock = multiprocessing.Lock()
counter = multiprocessing.Value('i', 0) # Shared memory object of type
integer.

processes = [multiprocessing.Process(target=increment, args=(counter,


lock)) for _ in range(5)]

for p in processes:
p.start()

for p in processes:
p.join()

print("Final counter value:", counter.value)

Explanation:

• Lock ensures that only one process can increment the counter at a time.
• multiprocessing.Value() is used for sharing data between processes.

6. Shared Memory with Value and Array

6.1 Using Value for Shared Variables

Value is used to share a single value between processes.

Example:

from multiprocessing import Process, Value

def add_to_value(val):
val.value += 1

if __name__ == "__main__":
val = Value('i', 0) # 'i' means integer
processes = [Process(target=add_to_value, args=(val,)) for _ in
range(10)]

for p in processes:
p.start()

for p in processes:
p.join()

print("Final Value:", val.value)

7. Exercises

7.1 Exercise 1: Implementing a Parallel Factorial Calculator

• Write a program that calculates the factorial of numbers using multiple processes.
• Use a Pool to divide the workload among processes.

7.2 Exercise 2: Simulating a Producer-Consumer Problem

• Implement a producer-consumer scenario using Queue.


• One process should produce random numbers, and another should consume and print
them.
7.3 Exercise 3: Synchronizing Counter Increment

• Create a program where multiple processes increment a shared counter.


• Use Lock to ensure that each process increments the counter without conflicts.

7.4 Exercise 4: Discuss the challenges and advantages of parallel programming in Python.
Include examples of scenarios where it would be beneficial to use multiprocessing or
threading.

8. Summary

• Multiprocessing allows parallelism by creating separate processes.


• Use Process for simple processes.
• Use Pool for handling multiple tasks.
• Use Queue for inter-process communication.
• Use Lock for synchronization.

9. Additional Resources

• Python Documentation: https://docs.python.org/3/library/multiprocessing.html


• Tutorial on Multiprocessing in Python: Real Python

You might also like