Bypassing GIL

Python SELF EN
Level 26 , Lesson 4
Available

11.1 Global Interpreter Lock

Global Interpreter Lock (GIL) is a mechanism in the CPython interpreter that ensures only one thread executes Python bytecode at a time. GIL prevents threads from running in parallel, which can negatively impact the performance of multithreaded programs, especially on multicore processors.

Reasons for GIL existence

Simplifies memory management: GIL simplifies memory management and garbage collection, making Python easier to implement.

Thread safety: GIL prevents race conditions, making the code execution thread-safe without the need to use locks.

Issues caused by GIL

Limited performance: Multithreaded programs performing computationally intensive tasks cannot fully exploit the benefits of multicore processors due to the limitations of GIL.

Performance distortion: Programs that heavily use threads to perform tasks may experience degraded performance due to context switching between threads.

Currently, there are 4 main ways to "bypass GIL":

11.2 Using Multiprocessing (multiprocessing)

The multiprocessing module allows you to create processes that run in parallel and are not limited by GIL, since each process has its own Python interpreter and memory.

Example:


import multiprocessing

def worker(num):
    print(f'Worker: {num}')
            
def main():
    processes = []
    for i in range(5):
        p = multiprocessing.Process(target=worker, args=(i,))
        processes.append(p)
        p.start()
            
    for p in processes:
        p.join()
            
main()

11.3 Asynchronous Programming

Asynchronous programming using asyncio allows tasks to run concurrently without blocking the main thread. While it doesn't bypass GIL in the direct sense, it enables efficient use of wait times for performing other tasks.

Example:


import asyncio

async def main():
    await asyncio.sleep(1)
    print('Hello')
            
asyncio.run(main())

11.4 Using Libraries with Native Threading

Some libraries, like NumPy and SciPy, are written in C and use their own threading mechanisms, which allows them to bypass GIL and efficiently use multicore processors for computations.

Really, this is one of the main reasons for Python's success, no matter how slow it is. All complex calculations are rewritten in C/C++ and executed across all CPU cores or even directly on GPU cores. Modern GPUs have thousands of cores.

So, it doesn't matter anymore how fast or slow a language is, if all resource-intensive computations are done by external libraries or are offloaded to remote data centers.

11.5 Performing Computations Outside the Python Interpreter

Using C/C++ extensions or other languages that can perform computations outside the Python interpreter and then return the result. This avoids GIL blocking during intensive computations.

Example using Cython:


# example.pyx

def compute(int n):
    cdef int i, result = 0
    for i in range(n):
        result += i
    return result

Compilation and usage:


cythonize -i example.pyx

import example
print(example.compute(1000000))
2
Task
Python SELF EN, level 26, lesson 4
Locked
Using Multiprocessing
Using Multiprocessing
2
Task
Python SELF EN, level 26, lesson 4
Locked
Asynchronous Programming
Asynchronous Programming
1
Опрос
Asynchrony,  26 уровень,  4 лекция
недоступен
Asynchrony
Asynchrony
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION