[go: up one dir, main page]

0% found this document useful (0 votes)
24 views5 pages

301 Assignment

The document discusses threading in Python, explaining its definition, shared memory benefits, and optimal use for I/O-bound tasks. It also covers the Global Interpreter Lock (GIL), which restricts true parallelism for CPU-bound tasks, and presents alternatives like multiprocessing, optimized libraries, and asyncio to overcome GIL limitations. Additional options include Cython, subprocesses, and distributed frameworks for handling larger workloads.

Uploaded by

hshawon561
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
24 views5 pages

301 Assignment

The document discusses threading in Python, explaining its definition, shared memory benefits, and optimal use for I/O-bound tasks. It also covers the Global Interpreter Lock (GIL), which restricts true parallelism for CPU-bound tasks, and presents alternatives like multiprocessing, optimized libraries, and asyncio to overcome GIL limitations. Additional options include Cython, subprocesses, and distributed frameworks for handling larger workloads.

Uploaded by

hshawon561
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 5

ASSIGNMENT

on
“Threading in Python”
Course Code: PROG 301

Submitted by:
Istiaque Ahmed
ID NO. 2201027 of 2022-2023
4th Semester, B.Sc.

Submitted to:
Farzana Akter
Assistant Professor

Department of IoT and Robotics Engineering,


Gazipur Rahman Digital University
Kaliakoir, Gazipur
Threading in Python, the Role of the GIL, and
Alternatives
1) Threading in Python

• Definition: Threading is a way of running multiple parts of a program (called


threads) at the same time within a single Python process.
• Shared memory: All threads share the same memory space, which makes
communication between them easier compared to separate processes.
• Best use case: Threading works best for I/O-bound tasks (like downloading files,
reading from disk, or making network requests) where the program spends time
waiting.

Example (I/O-bound):

Without threads this would take 4 seconds; with threads it finishes in ~2 seconds because
waiting overlaps.
2) The Global Interpreter Lock (GIL)

• What it is: In CPython (the main Python interpreter), there is a mechanism called the
Global Interpreter Lock (GIL).
• How it works: The GIL only allows one thread to execute Python bytecode at a
time, even if the computer has many CPU cores.
• Impact: This means threads cannot achieve true parallelism for CPU-heavy work.
They take turns running Python code.
• Good for: I/O-bound tasks (where waiting happens).
• Bad for: CPU-bound tasks (like mathematical calculations).

Example (CPU-bound):

Even with 2 threads, the time is almost the same as running once, because of the GIL.
3) Alternatives to Overcome GIL Limitations

a) Multiprocessing

• Each process has its own Python interpreter and its own GIL, so they can run truly
in parallel on multiple CPU cores.
• Best for CPU-heavy work.

from multiprocessing import Process


import time

def count():
total = 0
for i in range(50_000_00):
total += i

p1 = Process(target=count)
p2 = Process(target=count)

start = time.time()
p1.start(); p2.start()
p1.join(); p2.join()
end = time.time()

print("Time with processes:", end - start)

b) Optimized Libraries (NumPy, Pandas, etc.)

• Many scientific libraries are written in C/C++ and release the GIL while performing
heavy calculations.
• They allow Python code to indirectly use multiple cores.

import numpy as np
a = np.arange(10_000_0)
b = a * a # very fast, no GIL issue

c) Asyncio

• Provides concurrency using an event loop instead of threads.


• Best for handling thousands of I/O tasks at once.

import asyncio

async def worker(name):


print(f"Starting {name}")
await asyncio.sleep(2)
print(f"Finished {name}")

async def main():


await asyncio.gather(worker("Task-1"), worker("Task-2"))

asyncio.run(main())

d) Other options:
• Cython / Numba (compile Python code and release GIL)
• External programs via subprocess (e.g., call ffmpeg for video tasks)
• Distributed frameworks like Dask or Ray for very large workloads

You might also like