Concurrency in Python: Seamlessly Managing Multiple Processes Simultaneously
In the arena of computer science, concurrency has always been a notable topic. With Python’s continuously evolving landscape, developing a clear understanding of concurrency can ensure you’re taking full advantage of this feature-rich language. Strap in as we traverse this fascinating aspect of Python together.
What is Concurrency in Python?
Simply put, concurrency is the competence of your Python program to handle many tasks at the same time. Imagine you’re a juggler, and each juggling ball represents a process. The better you juggle, the more efficiently you manage your processes. But don’t worry, Python concurrency won’t literally have you juggling – though wouldn’t that be a party trick? The Python official documentation provides excellent details if you wish to dive deeper.
How Python Handles Concurrency
Python employs multiple built-in libraries and functionalities that allow for effective management of concurrent tasks. Some of the most popular methods include threads, multiprocessing, asyncio, and concurrent.futures.
import threading
def print_cube(num):
"""
function to print cube of given num
"""
print(f"Cube: {num * num * num}")
def print_square(num):
"""
function to print square of given num
"""
print(f"Square: {num * num}")
if __name__ == "__main__":
# creating thread
t1 = threading.Thread(target=print_square, args=(10,))
t2 = threading.Thread(target=print_cube, args=(10,))
# starting thread 1
t1.start()
# starting thread 2
t2.start()
# wait until thread 1 is completely executed
t1.join()
# wait until thread 2 is completely executed
t2.join()
# both threads completely executed
print("Done!")
Above is a basic example of using threads to handle multiple processes simultaneously.
Taming the Beast: The Global Interpreter Lock (GIL)
One key element to understand when discussing concurrency in Python is the infamous Global Interpreter Lock (GIL). The GIL is a mechanism that allows only one thread to execute at a time in a single process, which might sound like it would slow things down. Rest assured, Python always has a trick up its sleeve. Python uses thread switching to ensure that all threads get fair CPU time. Let’s face it, Python wasn’t opting for a ‘survival of the fittest’ scenario here.
Beyond Threads: Multiprocessing and Asynchronous I/O
When threading isn’t enough to handle your load, Python introduces multiprocessing and asynchronous I/O (asyncio) as its heavy hitters.
Multiprocessing in Python is used for executing heavy computation tasks that require more CPU time. It creates and manages processes that run concurrently. Under the hood, it’s Python’s way of saying, “Hey, I’ve got some extra cores. Let’s put them to work.”
from multiprocessing import Process
def print_func(continent='Asia'):
print(f'The name of continent is: {continent}')
if __name__ == "__main__": # confirms that the code is under main function
names = ['America', 'Europe', 'Africa']
procs = []
proc = Process(target=print_func) # instantiating without any argument
procs.append(proc)
proc.start()
# instantiating process with arguments
for name in names:
# print(name)
proc = Process(target=print_func, args=(name,))
procs.append(proc)
proc.start()
# complete the processes
for proc in procs:
proc.join()
Asyncio, on the other hand, is used for IO-bound tasks. It’s Python’s solution for handling thousands of connections with ease, crucial in the era of the cloud. If threading is Python’s way of juggling, asyncio is Python’s way of spinning plates.
Final Words
Concurrency is indeed a comprehensive topic. But understanding and applying concurrency in Python can revolutionize the way you design and develop Python applications. With multiprocessing, threading, and asyncio in your toolbox, you can sit back, relax, and let Python do the multitasking. All you’ll be needing to master next is the art of sipping your coffee while Python handles your tasks, and if you master that, do remember to share your secret!
References
1. Python threading library
2. Python multiprocessing library
3. Python asyncio library
4. Real Python – Concurrency