Section Notes
Practical Session about Multithreading vs multiprocessing
By Dr. Ebtisam El-Hossiny
1. Multithreading in Python
Multithreading allows the execution of multiple threads (smaller units of a process)
concurrently within a single process. Ideal for I/O bound tasks (e.g., network
requests, disk I/O).
import threading
import time
def print_numbers():
for i in range(5):
time.sleep(1)
print(f"Number: {i}")
def print_letters():
for letter in ['A', 'B', 'C', 'D', 'E']:
time.sleep(1)
print(f"Letter: {letter}")
# Creating threads
t1 = threading.Thread(target=print_numbers)
t2 = threading.Thread(target=print_letters)
# Starting threads
t1.start()
t2.start()
# Wait for both threads to complete
t1.join()
t2.join()
print("Both threads completed!")
Session Notes in Python Distributed Computing By: Dr. Ebtisam El-Hossiny 1
Explanation:
• threading.Thread: Creates a new thread.
• .start(): Begins execution of the thread.
• .join(): Waits for the thread to finish before proceeding.
•
Output:
Limitation
Due to Python's Global Interpreter Lock (GIL), only one thread can execute Python
bytecode at a time. This makes multithreading less `-bound tasks.
Session Notes in Python Distributed Computing By: Dr. Ebtisam El-Hossiny 2
Session about Multiprocessing
2. Multiprocessing in Python
Multiprocessing creates separate processes, each with its own Python interpreter and
memory space. It bypasses the GIL, allowing true parallelism on multi-core systems,
making it ideal for CPU-bound tasks (e.g., heavy computations, data processing).
from multiprocessing import Process
import time
def calculate_square(numbers):
for n in numbers:
time.sleep(1)
print(f"Square of {n} is {n * n}")
def calculate_cube(numbers):
for n in numbers:
time.sleep(1)
print(f"Cube of {n} is {n * n * n}")
numbers = [1, 2, 3, 4, 5]
if __name__ == '__main__':
# Creating processes
p1 = Process(target=calculate_square, args=(numbers,))
p2 = Process(target=calculate_cube, args=(numbers,))
# Starting processes
p1.start()
p2.start()
# Wait for processes to complete
p1.join()
p2.join()
print("Both processes completed!")
Output:
Session Notes in Python Distributed Computing By: Dr. Ebtisam El-Hossiny 3
Explanation:
• Process: Represents a separate process.
• .start() and .join() are used similarly to threads.
• Advantage: Each process runs in its own memory space, avoiding GIL limitations.
Summary
1. Multithreading is best for tasks that wait, like I/O operations.
2. Multiprocessing is best for computationally intensive tasks.
3. Both approaches improve performance through concurrency but are suited for
different scenarios.
Session Notes in Python Distributed Computing By: Dr. Ebtisam El-Hossiny 4