title: Python: what are the advantages of async over threads?
body: <p>I've had a hard time trying to understand how and why async functionality works in python and I am still not sure I understand everything correctly (especially the 'why' part). Please correct me if I am wrong.</p>
  
  <p>The purpose of both async methods and threads is to make it possible to process several tasks concurrently.</p>
  
  <p>Threads approach looks simple and intuitive. If python program processes several tasks concurrently we have a thread (may be with sub-threads) for each task, the stack of each thread reflects the current stage of processing of corresponding task. Everything is straightforward, there are easy-to-use mechanisms to start a new thread and wait for results from it.</p>
  
  <p>As I understand the only problem with this approach is that threads are expensive.</p>
  
  <p>Another approach is using <code>async</code> coroutines. I can see several inconveniences with this approach. I'll name couple of them only. We have now two types of methods: usual methods and <code>async</code> methods. 90% of the time the only difference is that you need to remember that this method is <code>async</code> and do not forget to use <code>await</code> keyword when calling this method. And yes, you can't call <code>async</code> method from normal ones. And all this <code>async</code> - <code>await</code> syntactic garbage all around the program is only to indicate that this method is able to yield control to message loop.</p>
  
  <p>Threads approach is free of all these inconveniences. But <code>async</code> - <code>await</code> approach allows to process much more concurrent tasks than threads approach does. How is that possible?</p>
  
  <p>For each concurrent task we still have a call stack, only now it is a coroutine call stack. I am not quite sure, but looks like this is the key difference: usual stacks are operating-system stacks, they are expensive, coroutine stacks are just a python structures, they are much cheaper. Is this my understanding correct?</p>
  
  <p>If this is correct, wouldn't it be better to decouple python threads/call stacks from OS threads/call stacks to make python threads cheaper?</p>
  
  <p>Sorry if this question is stupid. I am sure there are some reasons why <code>async</code>-<code>await</code> approach was selected. Just want to understand these reasons.</p>
  
  <p><strong>Update:</strong></p>
  
  <p>For those who do not think this question is not good and too broad.</p>
  
  <p>Here is an article <a href="https://glyph.twistedmatrix.com/2014/02/unyielding.html" rel="noreferrer">Unyielding</a> - which starts with explanations why threads are bad and advertises <code>async</code> approach. Main thesis: threads are evil, it's too difficult to reason about a routine that may be executed from arbitrary number of threads concurrently.</p>
  
  <p>Thanks to Nathaniel J. Smith (author of python <a href="https://github.com/python-trio/trio" rel="noreferrer">Trio</a> library) who suggested this link.</p>
  
  <p>By the way, arguments in the article are not convincing for me, but still may be useful.</p>