Concurrency in Python

Concurrency in Python

Concurrency creates the illusion of parallelism by switching between tasks while parallelism is doing many tasks at the same time.

There are several ways to make a Python application concurrently. It depends on the architecture and the requirements of the software which one to use. Here are three libraries and architecture solutions to increase the speed:


Multiprocessing

A Python library for creating and managing processes. It's a good idea to use this if your application is CPU bound, such as for training an AI model or for audio/image processing because it can truly parallelize. Also, it's the most expensive because of the overhead of creating a process and because each process needs its own memory space. Here is an example:

from multiprocessing import Process

def do_something(): ...

def do_something_else(): ...

def main():
    process1 = Process(target=do_something)
    process2 = Process(target=do_something_else)

    # run the processes in parallel
    process1.start()
    process2.start()

    # wait for processes to finish
    process1.join()
    process2.join()

if __name__ == "__main__":
    main()        


Threading

A Python library to work with threads. It's a good choice if you need intercommunication because they share memory, which makes communication faster than using processes. Also, it's better when your application is IO bound, such as querying a database or making network requests. Because of the Python GIL we cannot parallelize threads of a process. Here is an example:

from threading import Thread

def do_something(): ...

def do_something_else(): ...

def main():
    thread1 = Thread(target=do_something)
    thread2 = Thread(target=do_something_else)

    # run the threads concurrently
    thread1.start()
    thread2.start()

    # wait for threads to finish
    thread1.join()
    thread2.join()

if __name__ == "__main__":
    main()        


Asyncio

A Python library that allows us to run multiples coroutines in a single thread using the async/await syntax. Use it when your application is IO bound and you need to scale it. Asynchronous code can often be more readable and maintainable compared to traditional threading or multiprocessing. Here is an example:

import asyncio

async def do_something(): ...

async def do_something_else(): ...

async def main():
    # run the coroutines concurrently
    await asyncio.gather(do_something(), do_something_else())

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


In conclusion, concurrency offers a powerful approach to improve the performance of Python applications. By understanding the strengths and limitations of these libraries, you can take decisions to optimize your code.

Santiago Cuadrado Vilar

Software Engineer at @Foliume

9 个月

Nice post Danilo!

Juan Medina

Full Stack Developer at Eron

9 个月

Well explained Dani!

要查看或添加评论,请登录

Danilo Nu?ez的更多文章

  • Metaprogramming using metaclasses in Python

    Metaprogramming using metaclasses in Python

    We all have heard a lot about basic concepts classes in Python like their syntax, their attributes, how to create…

社区洞察

其他会员也浏览了