Abhishek G
Abhishek G

Reputation: 118

What is the difference between using Python's threading versus async/await

Im trying to get more familiar in the usage of asyncio in python3, but I dont see when i should use async/await or threading. Is there a difference or is one just easier to use than the other.

So for example between these two functions, is one better than the other?

Just generic code

def func1()
def func2()

threads = [threading.Thread(target=func1), threading.Thread(target=func2)]
for thread in threads:
    thread.start()

for thread in threads:
    thread.join()

versus

async def func1()
async def func2()

await asyncio.gather(func1(), func2())

Upvotes: 4

Views: 2063

Answers (2)

benrg
benrg

Reputation: 1899

My advice is to use threads in all cases, unless you're writing a high-performance concurrent application and benchmarking shows that threading alone is too slow.

In principle there are a lot of things to like about coroutines. They're easier to reason about since every sequence of nonblocking operations can be treated as atomic (at least if you don't combine them with threads); and because they're cheap, you can spin them up willy-nilly for better separation of concerns, without worrying about killing your performance.

However, the actual implementation of coroutines in Python is a mess. The biggest problem is that every function that might block, or that might call any code that might block, or that might call any code that ... might call any code that might block, has to be rewritten with the async and await keywords. This means that if you want to use a library that blocks, or that calls back into your code and you want to block in the callbacks, then you just can't use that library at all. There are duplicate copies of a bunch of libraries in the CPython distribution now for this reason, and even duplicate copies of built-in syntax (async for, etc.), but you can't expect most of the modules available through pip to be maintained in two versions.

Threading doesn't have this problem. If a library wasn't designed to be thread safe, you can still use it in a multithreaded program, either by confining its use to one thread or by protecting all uses with a lock.

So threading is overall far easier to use in Python despite its problems.

There are some third party coroutine solutions that avoid the "async infection" problem, such as greenlet, but you still won't be able to use them with libraries that block internally unless they're specially designed to work with coroutines.

Upvotes: 6

algorythms
algorythms

Reputation: 1585

With asyncio, a piece of code can take back control using await. With threads, this is handled by the Python scheduler. Multithreading puts into place a locking mechanism to prevent issues with shared memory. Another advantage of multithreading is it is able to use several cores.

Here is a great article if you want to read more: https://medium.com/@nhumrich/asynchronous-python-45df84b82434

Upvotes: 1

Related Questions