When working with processes, Python employs a form of process lock called the Global Interpreter Lock (GIL). Python typically executes a collection of typed statements using just one thread. It simply explains that any one thread for a time will be done in Python. Python's GIL makes it possible for single- and multi-threaded processes to run equally well. Python does not support multithreading because it has a global interpreter lock that limits the number of threads and makes each thread act as a single thread.
Why do Python Programmers use GIL?
For memory management, Python has a tool known as a reference counter. The reference counter keeps track of all internal Python references used to give a data object a value. Because when references counters reach 0, the object releases the space that was allocated to it. The reference count variable's main drawback is that it may be impacted if two or three threads attempt to increase or reduce its value at the same time. It's called a "race condition." If this issue develops, it may be the result of memory that has been leaky but never released. The Python application can have flaws or crash.
Python issues Resolved by the GIL:
A reference counter is just something that Python possesses that neither language does. The number of references that Python makes internally to assign a monetary value to a data object can be counted with the aid of the reference counter. This counter allows us to keep track of the references, and when the count drops to zero, the variable or data object is immediately removed.
# example Python program for implementing # the use of reference counter import sys # assign value to the variable x = "javatpoint" print(sys.getrefcount(x)) y = x print(sys.getrefcount(y))
This reference counter variable needed to be protected because it is possible for two threads to modify it simultaneously, which could result in memory leaks. To prevent this, we added locks to all data structures that were shared by multiple threads, but occasionally this led to multiple locks, which resulted in a deadlock, which is a different issue. We utilised a single lock on the interpreter called the Global Interpreter Lock to prevent memory leaks and deadlocks (GIL).
Effect on Python Programs with Multiple Threads
When it comes to performance, CPU-bounds and I/O-bounds are different for a normal Python programme or any other type of computer programme. Programs that are CPU-bound typically push the CPU to its limits. Mathematical computations like matrix multiplications, scorching, image processing, etc. are typically performed using these programmes.
Programs that require a lot of input or output from a user, file, database, network, etc. are said to be I/O-bound. Such programmes must wait till the input from the source for a sizable period of time. The source, on the other hand, also has a processing time. As an illustration, imagine a user considering what to enter as an input.
Example 1 : CPU bound program
# example Python program for implementing # the use of CPU bound algorithm import time from threading import Thread # declare the count c = 10000000 def countdown(x): while x>0: x = x - 1 # first f = time.time() countdown(c) # last l = time.time() # print the amount of time taken print('Total time is = ', l - f)
Total time is = 0.6801362037658691
Example 2: Two threads Running Parallelly
# example Python program for implementing # the use of two threads running parallelly # import the requires packages import time from threading import Thread # declare the count c = 10000000 def countdown(x): while x>0: x = x - 1 time1 = Thread(target = countdown, args =(c//2, )) time2 = Thread(target = countdown, args =(c//2, )) f = time.time() time1.start() time2.start() time1.join() time2.join() l = time.time() # print the time taken print('Total time is = ', l - f)
Total time is = 0.7371137142181396
Why the GIL hasn't been taken out yet:
GIL is not currently improved because Python 2 already implements GIL, and if we modify this in Python 3, we will run into issues. So rather than getting rid of GIL, we enhance it. Python's reliance on C and its extension's need on GIL's implementation techniques in the backend are two reasons why the GIL shouldn't be removed just yet. Although there are many more ways to address the issues that GIL addresses, the majority of them are challenging to put into practise and may cause the system to lag.
What to do about Python's GIL:
Typically, we employ multiprocessing to shield the programme from GIL. Although Python takes a better interpreter with each task to employ, each process is granted a single message in this variation of multi-processing.
# example Python program for implementing # the use of multiprocessing # importing required packages import multiprocessing import time # declare the count c = 10000000 def countdown(x): while x>0: x = x - 1 if __name__ == "__main__": # creating processes f = time.time() process1 = multiprocessing.Process(target = countdown, args =(c//2, )) process2 = multiprocessing.Process(target = countdown, args =(c//2, )) process1.start() process2.start() # join() method for waiting until processes # are finished process1.join() process2.join() l = time.time() # print the time taken print('Total time is = ', l - f)
Total time is = 0.26715660095214844
The amount of time required by a multi-processing system and a multi-threaded system is the same. This is so that a multi-processing system may address its own set of issues. Therefore, this won't address the issue, but it does offer the workaround that Python is permitted to implement under GIL.
- GIL contributes to the elimination of this issue by providing lock to every common data structure throughout threads to prevent their inconsistent modification.
- Python offers a simple method for implementing the GIL because it handles thread-safe memory management.
- For Python to process GIL, a thread must be given a single lock. A single-threaded programme performs better since just one lock needs to be.
- Additionally, it aids in making any CPU-bound software and avoids the situation known as a deadlock.