Streamline Your Python Code with Asynchronous Functions

Introduction

In this article, we will learn about what are the ways to run a Python function asynchronously. In Python, there are several ways to run a function asynchronously, which means executing it concurrently without blocking the main thread of execution.

Using the threading module

The threading module allows you to create and manage threads in Python. Each thread runs concurrently, and you can use them to run functions asynchronously.

import threading
import time

def my_function(name):
    print(f"Thread {name}: starting")
    time.sleep(2)  # make thread sleep
    print(f"Thread {name}: finished")

if __name__ == "__main__":
    thread1 = threading.Thread(target=my_function, args=("Thread-1",))
    thread2 = threading.Thread(target=my_function, args=("Thread-2",))

    thread1.start()
    thread2.start()

    thread1.join()
    thread2.join()
    print("Main thread: finished")

In the above example, We create two threads (thread1 and thread2) that execute the my_function concurrently. The start() method starts the execution of the thread, and the join() method waits for the thread to complete before allowing the main thread to continue.

Using the asyncio module

The asyncio module provides a more modern and efficient way of handling asynchronous code in Python. It uses coroutines and an event loop to manage concurrent execution.

import asyncio
import time

async def my_function(name):
    print(f"Task {name}: starting")
    await asyncio.sleep(2)  
    print(f"Task {name}: finished")

async def main():
    task1 = asyncio.create_task(my_function("Task-1"))
    task2 = asyncio.create_task(my_function("Task-2"))
    await task1
    await task2

if __name__ == "__main__":
    asyncio.run(main())
    print("main function finished")

In the above example, we define an asynchronous function my_function using the async keyword. Inside the main function, we create two tasks (task1 and task2) that execute my_function concurrently. The await keyword is used to pause the coroutine execution until the task is completed.

Using the multiprocessing module

The multiprocessing module allows you to create and manage processes in Python. Each process runs independently, leveraging multiple CPU cores if available.

import multiprocessing
import time

def my_function(name):
    print(f"Process {name}: starting")
    time.sleep(2)  
    print(f"Process {name}: finished")

if __name__ == "__main__":
    process1 = multiprocessing.Process(target=my_function, args=("Process-1",))
    process2 = multiprocessing.Process(target=my_function, args=("Process-2",))

    process1.start()
    process2.start()
    process1.join()
    process2.join()
    print("Main process is finished")

In the above example, we create two processes (process1 and process2) that execute the my_function concurrently. The start() method starts the execution of the process, and the join() method waits for the process to complete before allowing the main process to continue.

Summary

Each approach has its own advantages and use cases. The threading module is lightweight and suitable for I/O-bound tasks, while the multiprocessing module is better suited for CPU-bound tasks due to the Global Interpreter Lock (GIL) limitation in Python. The asyncio module provides a more modern and efficient approach for handling asynchronous code, especially in network-related applications.


Similar Articles