403Webshell
Server IP : 121.121.20.254  /  Your IP : 216.73.216.142
Web Server : Microsoft-IIS/10.0
System : Windows NT WEB-SERVER 10.0 build 20348 (Windows Server 2022) AMD64
User : IUSR ( 0)
PHP Version : 8.3.28
Disable Function : NONE
MySQL : ON  |  cURL : ON  |  WGET : OFF  |  Perl : OFF  |  Python : OFF  |  Sudo : OFF  |  Pkexec : OFF
Directory :  C:/Python315/Doc/html/howto/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : C:/Python315/Doc/html/howto/a-conceptual-overview-of-asyncio.html
<!DOCTYPE html>

<html lang="en" data-content_root="../">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<meta property="og:title" content="A conceptual overview of asyncio" />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://docs.python.org/3/howto/a-conceptual-overview-of-asyncio.html" />
<meta property="og:site_name" content="Python documentation" />
<meta property="og:description" content="This HOWTO article seeks to help you build a sturdy mental model of how asyncio fundamentally works, helping you understand the how and why behind the recommended patterns. You might be curious abo..." />
<meta property="og:image" content="_static/og-image.png" />
<meta property="og:image:alt" content="Python documentation" />
<meta name="description" content="This HOWTO article seeks to help you build a sturdy mental model of how asyncio fundamentally works, helping you understand the how and why behind the recommended patterns. You might be curious abo..." />
<meta name="theme-color" content="#3776ab">
<meta property="og:image:width" content="200">
<meta property="og:image:height" content="200">

    <title>A conceptual overview of asyncio &#8212; Python 3.15.0rc1 documentation</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
    
    <link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=b86133f3" />
    <link rel="stylesheet" type="text/css" href="../_static/classic.css?v=234b1a7c" />
    <link rel="stylesheet" type="text/css" href="../_static/pydoctheme.css?v=4365c8fe" />
    <link id="pygments_dark_css" media="(prefers-color-scheme: dark)" rel="stylesheet" type="text/css" href="../_static/pygments_dark.css?v=0fc419ee" />
    
    <script src="../_static/documentation_options.js?v=791e38b1"></script>
    <script src="../_static/doctools.js?v=9bcbadda"></script>
    <script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
    
    <script src="../_static/sidebar.js"></script>
    
    <link rel="search" type="application/opensearchdescription+xml"
          title="Search within Python 3.15.0rc1 documentation"
          href="../_static/opensearch.xml"/>
    <link rel="author" title="About these documents" href="../about.html" />
    <link rel="index" title="Index" href="../genindex.html" />
    <link rel="search" title="Search" href="../search.html" />
    <link rel="copyright" title="Copyright" href="../copyright.html" />
    <link rel="next" title="Porting Extension Modules to Python 3" href="cporting.html" />
    <link rel="prev" title="Python HOWTOs" href="index.html" />
    
      
      <link rel="canonical" href="https://docs.python.org/3/howto/a-conceptual-overview-of-asyncio.html">
      
    

    
    <style>
      @media only screen {
        table.full-width-table {
            width: 100%;
        }
      }
    </style>
<link rel="stylesheet" href="../_static/pydoctheme_dark.css" media="(prefers-color-scheme: dark)" id="pydoctheme_dark_css">
    <link rel="shortcut icon" type="image/png" href="../_static/py.svg">
            <script type="text/javascript" src="../_static/copybutton.js"></script>
            <script type="text/javascript" src="../_static/menu.js"></script>
            <script type="text/javascript" src="../_static/search-focus.js"></script>
            <script type="text/javascript" src="../_static/themetoggle.js"></script> 
            <script type="text/javascript" src="../_static/rtd_switcher.js"></script>
            <meta name="readthedocs-addons-api-version" content="1">

  </head>
<body>
<div class="mobile-nav">
    <input type="checkbox" id="menuToggler" class="toggler__input" aria-controls="navigation"
           aria-pressed="false" aria-expanded="false" role="button" aria-label="Menu">
    <nav class="nav-content" role="navigation">
        <label for="menuToggler" class="toggler__label">
            <span></span>
        </label>
        <span class="nav-items-wrapper">
            <a href="https://www.python.org/" class="nav-logo">
                <img src="../_static/py.svg" alt="Python logo">
            </a>
            <span class="version_switcher_placeholder"></span>
            <form role="search" class="search" action="../search.html" method="get">
                <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" class="search-icon">
                    <path fill-rule="nonzero" fill="currentColor" d="M15.5 14h-.79l-.28-.27a6.5 6.5 0 001.48-5.34c-.47-2.78-2.79-5-5.59-5.34a6.505 6.505 0 00-7.27 7.27c.34 2.8 2.56 5.12 5.34 5.59a6.5 6.5 0 005.34-1.48l.27.28v.79l4.25 4.25c.41.41 1.08.41 1.49 0 .41-.41.41-1.08 0-1.49L15.5 14zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path>
                </svg>
                <input placeholder="Quick search" aria-label="Quick search" type="search" name="q">
                <input type="submit" value="Go">
            </form>
        </span>
    </nav>
    <div class="menu-wrapper">
        <nav class="menu" role="navigation" aria-label="main navigation">
            <div class="language_switcher_placeholder"></div>
            
<label class="theme-selector-label">
    Theme
    <select class="theme-selector" oninput="activateTheme(this.value)">
        <option value="auto" selected>Auto</option>
        <option value="light">Light</option>
        <option value="dark">Dark</option>
    </select>
</label>
  <div>
    <h3><a href="../contents.html">Table of Contents</a></h3>
    <ul>
<li><a class="reference internal" href="#">A conceptual overview of <code class="xref py py-mod docutils literal notranslate"><span class="pre">asyncio</span></code></a><ul>
<li><a class="reference internal" href="#a-conceptual-overview-part-1-the-high-level">A conceptual overview part 1: the high-level</a><ul>
<li><a class="reference internal" href="#event-loop">Event loop</a></li>
<li><a class="reference internal" href="#asynchronous-functions-and-coroutines">Asynchronous functions and coroutines</a></li>
<li><a class="reference internal" href="#tasks">Tasks</a></li>
<li><a class="reference internal" href="#await">await</a><ul>
<li><a class="reference internal" href="#awaiting-tasks">Awaiting tasks</a></li>
<li><a class="reference internal" href="#awaiting-coroutines">Awaiting coroutines</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#a-conceptual-overview-part-2-the-nuts-and-bolts">A conceptual overview part 2: the nuts and bolts</a><ul>
<li><a class="reference internal" href="#the-inner-workings-of-coroutines">The inner workings of coroutines</a></li>
<li><a class="reference internal" href="#futures">Futures</a></li>
<li><a class="reference internal" href="#a-homemade-asyncio-sleep">A homemade asyncio.sleep</a></li>
</ul>
</li>
</ul>
</li>
</ul>

  </div>
  <div>
    <h4>Previous topic</h4>
    <p class="topless"><a href="index.html"
                          title="previous chapter">Python HOWTOs</a></p>
  </div>
  <div>
    <h4>Next topic</h4>
    <p class="topless"><a href="cporting.html"
                          title="next chapter">Porting Extension Modules to Python 3</a></p>
  </div>
  <script>
    document.addEventListener('DOMContentLoaded', () => {
        const title = document.querySelector('meta[property="og:title"]').content;
        const elements = document.querySelectorAll('.improvepage');
        const pageurl = window.location.href.split('?')[0];
        elements.forEach(element => {
            const url = new URL(element.href.split('?')[0].replace("-nojs", ""));
            url.searchParams.set('pagetitle', title);
            url.searchParams.set('pageurl', pageurl);
            url.searchParams.set('pagesource', "howto/a-conceptual-overview-of-asyncio.rst");
            element.href = url.toString();
        });
    });
  </script>
  <div role="note" aria-label="source link">
    <h3>This page</h3>
    <ul class="this-page-menu">
      <li><a href="../bugs.html">Report a bug</a></li>
      <li><a class="improvepage" href="../improve-page-nojs.html">Improve this page</a></li>
      <li>
        <a href="https://github.com/python/cpython/blob/main/Doc/howto/a-conceptual-overview-of-asyncio.rst?plain=1"
            rel="nofollow">Show source
        </a>
      </li>
      
    </ul>
  </div>
        </nav>
    </div>
</div>

  
    <div class="related" role="navigation" aria-label="Related">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex.html" title="General Index"
             accesskey="I">index</a></li>
        <li class="right" >
          <a href="../py-modindex.html" title="Python Module Index"
             >modules</a> |</li>
        <li class="right" >
          <a href="cporting.html" title="Porting Extension Modules to Python 3"
             accesskey="N">next</a> |</li>
        <li class="right" >
          <a href="index.html" title="Python HOWTOs"
             accesskey="P">previous</a> |</li>

          <li><img src="../_static/py.svg" alt="Python logo" style="vertical-align: middle; margin-top: -1px"></li>
          <li><a href="https://www.python.org/">Python</a> &#187;</li>
          <li class="switchers">
            <div class="language_switcher_placeholder"></div>
            <div class="version_switcher_placeholder"></div>
          </li>
          <li>
              
          </li>
    <li id="cpython-language-and-version">
      <a href="../index.html">3.15.0rc1 Documentation</a> &#187;
    </li>

          <li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Python HOWTOs</a> &#187;</li>
        <li class="nav-item nav-item-this"><a href="">A conceptual overview of <code class="xref py py-mod docutils literal notranslate"><span class="pre">asyncio</span></code></a></li>
                <li class="right">
                    

    <div class="inline-search" role="search">
        <form class="inline-search" action="../search.html" method="get">
          <input placeholder="Quick search" aria-label="Quick search" type="search" name="q" id="search-box">
          <input type="submit" value="Go">
        </form>
    </div>
                     |
                </li>
            <li class="right">
<label class="theme-selector-label">
    Theme
    <select class="theme-selector" oninput="activateTheme(this.value)">
        <option value="auto" selected>Auto</option>
        <option value="light">Light</option>
        <option value="dark">Dark</option>
    </select>
</label> |</li>
            
      </ul>
    </div>    

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body" role="main">
            
  <section id="a-conceptual-overview-of-asyncio">
<span id="id1"></span><h1>A conceptual overview of <code class="xref py py-mod docutils literal notranslate"><span class="pre">asyncio</span></code><a class="headerlink" href="#a-conceptual-overview-of-asyncio" title="Link to this heading">¶</a></h1>
<p>This <a class="reference internal" href="index.html#how-tos"><span class="std std-ref">HOWTO</span></a> article seeks to help you build a sturdy mental
model of how <a class="reference internal" href="../library/asyncio.html#module-asyncio" title="asyncio: Asynchronous I/O."><code class="xref py py-mod docutils literal notranslate"><span class="pre">asyncio</span></code></a> fundamentally works, helping you understand the
how and why behind the recommended patterns.</p>
<p>You might be curious about some key <code class="xref py py-mod docutils literal notranslate"><span class="pre">asyncio</span></code> concepts.
By the end of this article, you’ll be able to comfortably answer these questions:</p>
<ul class="simple">
<li><p>What’s happening behind the scenes when an object is awaited?</p></li>
<li><p>How does <code class="xref py py-mod docutils literal notranslate"><span class="pre">asyncio</span></code> differentiate between a task which doesn’t need
CPU time (such as a network request or file read) as opposed to a task that
does (such as computing n-factorial)?</p></li>
<li><p>How to write an asynchronous variant of an operation, such as
an async sleep or database request.</p></li>
</ul>
<div class="admonition seealso">
<p class="admonition-title">See also</p>
<ul class="simple">
<li><p>The <a class="reference external" href="https://github.com/anordin95/a-conceptual-overview-of-asyncio/tree/main">guide</a> that inspired this HOWTO article, by Alexander Nordin.</p></li>
<li><p>This in-depth <a class="reference external" href="https://www.youtube.com/watch?v=Xbl7XjFYsN4&amp;list=PLhNSoGM2ik6SIkVGXWBwerucXjgP1rHmB">YouTube tutorial series</a> on
<code class="docutils literal notranslate"><span class="pre">asyncio</span></code> created by Python core team member, Łukasz Langa.</p></li>
<li><p><a class="reference external" href="https://aosabook.org/en/500L/a-web-crawler-with-asyncio-coroutines.html">500 Lines or Less: A Web Crawler With asyncio Coroutines</a> by A.
Jesse Jiryu Davis and Guido van Rossum.</p></li>
</ul>
</div>
<section id="a-conceptual-overview-part-1-the-high-level">
<h2>A conceptual overview part 1: the high-level<a class="headerlink" href="#a-conceptual-overview-part-1-the-high-level" title="Link to this heading">¶</a></h2>
<p>In part 1, we’ll cover the main, high-level building blocks of <code class="xref py py-mod docutils literal notranslate"><span class="pre">asyncio</span></code>:
the event loop, coroutine functions, coroutine objects, tasks, and <code class="docutils literal notranslate"><span class="pre">await</span></code>.</p>
<section id="event-loop">
<h3>Event loop<a class="headerlink" href="#event-loop" title="Link to this heading">¶</a></h3>
<p>Everything in <code class="xref py py-mod docutils literal notranslate"><span class="pre">asyncio</span></code> happens relative to the event loop.
It’s the star of the show, but prefers to work behind the scenes, managing
and coordinating resources.
It’s like an orchestra conductor.
Some power is explicitly granted to it, but a lot of its ability to get things
done comes from the respect and cooperation of its band members.</p>
<p>In more technical terms, the event loop contains a collection of jobs to be run.
Some jobs are added directly by you, and some indirectly by <code class="xref py py-mod docutils literal notranslate"><span class="pre">asyncio</span></code>.
The event loop takes a job from its backlog of work and invokes it (or “gives
it control”), similar to calling a function, and then that job runs.
Once it pauses or completes, it returns control to the event loop.
The event loop will then select another job from its pool and invoke it.
You can <em>roughly</em> think of the collection of jobs as a queue: jobs are added and
then processed one at a time, generally (but not always) in order.
This process repeats indefinitely, with the event loop cycling endlessly
onwards.
If there are no more jobs pending execution, the event loop is smart enough to
rest and avoid needlessly wasting CPU cycles, and will come back when there’s
more work to be done, such as when I/O operations complete or timers expire.</p>
<p>Effective execution relies on jobs sharing well and cooperating; a greedy job
could hog control and leave the other jobs to starve, rendering the overall
event loop approach rather useless.</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">asyncio</span>

<span class="c1"># This creates an event loop and indefinitely cycles through</span>
<span class="c1"># its collection of jobs.</span>
<span class="n">event_loop</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">new_event_loop</span><span class="p">()</span>
<span class="n">event_loop</span><span class="o">.</span><span class="n">run_forever</span><span class="p">()</span>
</pre></div>
</div>
</section>
<section id="asynchronous-functions-and-coroutines">
<h3>Asynchronous functions and coroutines<a class="headerlink" href="#asynchronous-functions-and-coroutines" title="Link to this heading">¶</a></h3>
<p>This is a basic, boring Python function:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span><span class="w"> </span><span class="nf">hello_printer</span><span class="p">():</span>
    <span class="nb">print</span><span class="p">(</span>
        <span class="s2">&quot;Hi, I am a lowly, simple printer, though I have all I &quot;</span>
        <span class="s2">&quot;need in life -- </span><span class="se">\n</span><span class="s2">fresh paper and my dearly beloved octopus &quot;</span>
        <span class="s2">&quot;partner in crime.&quot;</span>
    <span class="p">)</span>
</pre></div>
</div>
<p>Calling a regular function invokes its logic or body:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">hello_printer</span><span class="p">()</span>
<span class="go">Hi, I am a lowly, simple printer, though I have all I need in life --</span>
<span class="go">fresh paper and my dearly beloved octopus partner in crime.</span>
</pre></div>
</div>
<p>The <a class="reference internal" href="../reference/compound_stmts.html#async-def"><span class="std std-ref">async def</span></a>, as opposed to just a plain <code class="docutils literal notranslate"><span class="pre">def</span></code>, makes
this an asynchronous function (or “coroutine function”).
Calling it creates and returns a <a class="reference internal" href="../library/asyncio-task.html#coroutine"><span class="std std-ref">coroutine</span></a> object.</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">loudmouth_penguin</span><span class="p">(</span><span class="n">magic_number</span><span class="p">:</span> <span class="nb">int</span><span class="p">):</span>
    <span class="nb">print</span><span class="p">(</span>
     <span class="s2">&quot;I am a super special talking penguin. Far cooler than that printer. &quot;</span>
     <span class="sa">f</span><span class="s2">&quot;By the way, my lucky number is: </span><span class="si">{</span><span class="n">magic_number</span><span class="si">}</span><span class="s2">.&quot;</span>
    <span class="p">)</span>
</pre></div>
</div>
<p>Calling the async function, <code class="docutils literal notranslate"><span class="pre">loudmouth_penguin</span></code>, does not execute the print statement;
instead, it creates a coroutine object:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">loudmouth_penguin</span><span class="p">(</span><span class="n">magic_number</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span>
<span class="go">&lt;coroutine object loudmouth_penguin at 0x104ed2740&gt;</span>
</pre></div>
</div>
<p>The terms “coroutine function” and “coroutine object” are often conflated
as coroutine.
That can be confusing!
In this article, coroutine specifically refers to a coroutine object, or more
precisely, an instance of <a class="reference internal" href="../library/types.html#types.CoroutineType" title="types.CoroutineType"><code class="xref py py-class docutils literal notranslate"><span class="pre">types.CoroutineType</span></code></a> (native coroutine).
Note that coroutines can also exist as instances of
<a class="reference internal" href="../library/collections.abc.html#collections.abc.Coroutine" title="collections.abc.Coroutine"><code class="xref py py-class docutils literal notranslate"><span class="pre">collections.abc.Coroutine</span></code></a> – a distinction that matters for type
checking.</p>
<p>A coroutine represents the function’s body or logic.
A coroutine has to be explicitly started; again, merely creating the coroutine
does not start it.
Notably, the coroutine can be paused and resumed at various points within the
function’s body.
That pausing and resuming ability is what allows for asynchronous behavior!</p>
<p>Coroutines and coroutine functions were built by leveraging the functionality
of <a class="reference internal" href="../glossary.html#term-generator-iterator"><span class="xref std std-term">generators</span></a> and
<a class="reference internal" href="../glossary.html#term-generator"><span class="xref std std-term">generator functions</span></a>.
Recall, a generator function is a function that <a class="reference internal" href="../reference/simple_stmts.html#yield"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">yield</span></code></a>s, like this
one:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span><span class="w"> </span><span class="nf">get_random_number</span><span class="p">():</span>
    <span class="c1"># This would be a bad random number generator!</span>
    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Hi&quot;</span><span class="p">)</span>
    <span class="k">yield</span> <span class="mi">1</span>
    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Hello&quot;</span><span class="p">)</span>
    <span class="k">yield</span> <span class="mi">7</span>
    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Howdy&quot;</span><span class="p">)</span>
    <span class="k">yield</span> <span class="mi">4</span>
    <span class="o">...</span>
</pre></div>
</div>
<p>Similar to a coroutine function, calling a generator function does not run it.
Instead, it creates a generator object:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">get_random_number</span><span class="p">()</span>
<span class="go">&lt;generator object get_random_number at 0x1048671c0&gt;</span>
</pre></div>
</div>
<p>You can proceed to the next <code class="docutils literal notranslate"><span class="pre">yield</span></code> of a generator by using the
built-in function <a class="reference internal" href="../library/functions.html#next" title="next"><code class="xref py py-func docutils literal notranslate"><span class="pre">next()</span></code></a>.
In other words, the generator runs, then pauses.
For example:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">generator</span> <span class="o">=</span> <span class="n">get_random_number</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">next</span><span class="p">(</span><span class="n">generator</span><span class="p">)</span>
<span class="go">Hi</span>
<span class="go">1</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">next</span><span class="p">(</span><span class="n">generator</span><span class="p">)</span>
<span class="go">Hello</span>
<span class="go">7</span>
</pre></div>
</div>
</section>
<section id="tasks">
<h3>Tasks<a class="headerlink" href="#tasks" title="Link to this heading">¶</a></h3>
<p>Roughly speaking, <a class="reference internal" href="../library/asyncio-task.html#asyncio-task-obj"><span class="std std-ref">tasks</span></a> are coroutines (not coroutine
functions) tied to an event loop.
A task also maintains a list of callback functions whose importance will become
clear in a moment when we discuss <a class="reference internal" href="../reference/expressions.html#await"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">await</span></code></a>.</p>
<p>Creating a task automatically schedules it for execution (by adding a
callback to run it in the event loop’s to-do list, that is, collection of jobs).
The recommended way to create tasks is via <a class="reference internal" href="../library/asyncio-task.html#asyncio.create_task" title="asyncio.create_task"><code class="xref py py-func docutils literal notranslate"><span class="pre">asyncio.create_task()</span></code></a>.</p>
<p><code class="xref py py-mod docutils literal notranslate"><span class="pre">asyncio</span></code> automatically associates tasks with the event loop for you.
This automatic association was purposely designed into <code class="xref py py-mod docutils literal notranslate"><span class="pre">asyncio</span></code> for
the sake of simplicity.
Without it, you’d have to keep track of the event loop object and pass it to
any coroutine function that wants to create tasks, adding redundant clutter
to your code.</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">coroutine</span> <span class="o">=</span> <span class="n">loudmouth_penguin</span><span class="p">(</span><span class="n">magic_number</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span>
<span class="c1"># This creates a Task object and schedules its execution via the event loop.</span>
<span class="n">task</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">create_task</span><span class="p">(</span><span class="n">coroutine</span><span class="p">)</span>
</pre></div>
</div>
<p>Earlier, we manually created the event loop and set it to run forever.
In practice, it’s recommended to use (and common to see) <a class="reference internal" href="../library/asyncio-runner.html#asyncio.run" title="asyncio.run"><code class="xref py py-func docutils literal notranslate"><span class="pre">asyncio.run()</span></code></a>,
which takes care of managing the event loop and ensuring the provided
coroutine finishes before advancing.
For example, many async programs follow this setup:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">asyncio</span>

<span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">main</span><span class="p">():</span>
    <span class="c1"># Perform all sorts of wacky, wild asynchronous things...</span>
    <span class="o">...</span>

<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">&quot;__main__&quot;</span><span class="p">:</span>
    <span class="n">asyncio</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">main</span><span class="p">())</span>
    <span class="c1"># The program will not reach the following print statement until the</span>
    <span class="c1"># coroutine main() finishes.</span>
    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;coroutine main() is done!&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>It’s important to be aware that the task itself is not added to the event loop,
only a callback to the task is.
This matters if the task object you created is garbage collected before it’s
called by the event loop.
For example, consider this program:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="linenos"> 1</span><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">hello</span><span class="p">():</span>
<span class="linenos"> 2</span>    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;hello!&quot;</span><span class="p">)</span>
<span class="linenos"> 3</span>
<span class="linenos"> 4</span><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">main</span><span class="p">():</span>
<span class="linenos"> 5</span>    <span class="n">asyncio</span><span class="o">.</span><span class="n">create_task</span><span class="p">(</span><span class="n">hello</span><span class="p">())</span>
<span class="linenos"> 6</span>    <span class="c1"># Other asynchronous instructions which run for a while</span>
<span class="linenos"> 7</span>    <span class="c1"># and cede control to the event loop...</span>
<span class="linenos"> 8</span>    <span class="o">...</span>
<span class="linenos"> 9</span>
<span class="linenos">10</span><span class="n">asyncio</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">main</span><span class="p">())</span>
</pre></div>
</div>
<p>Because there’s no reference to the task object created on line 5, it <em>might</em>
be garbage collected before the event loop invokes it.
Later instructions in the coroutine <code class="docutils literal notranslate"><span class="pre">main()</span></code> hand control back to the event
loop so it can invoke other jobs.
When the event loop eventually tries to run the task, it might fail and
discover the task object does not exist!
This can also happen even if a coroutine keeps a reference to a task but
completes before that task finishes.
When the coroutine exits, local variables go out of scope and may be subject
to garbage collection.
In practice, <code class="docutils literal notranslate"><span class="pre">asyncio</span></code> and Python’s garbage collector work pretty hard to
ensure this sort of thing doesn’t happen.
But that’s no reason to be reckless!</p>
</section>
<section id="await">
<h3>await<a class="headerlink" href="#await" title="Link to this heading">¶</a></h3>
<p><a class="reference internal" href="../reference/expressions.html#await"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">await</span></code></a> is a Python keyword that’s commonly used in one of two
different ways:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">await</span> <span class="n">task</span>
<span class="k">await</span> <span class="n">coroutine</span>
</pre></div>
</div>
<p>In a crucial way, the behavior of <code class="docutils literal notranslate"><span class="pre">await</span></code> depends on the type of object
being awaited.</p>
<section id="awaiting-tasks">
<h4>Awaiting tasks<a class="headerlink" href="#awaiting-tasks" title="Link to this heading">¶</a></h4>
<p>Awaiting a task will cede control from the current task or coroutine to
the event loop.
In the process of relinquishing control, a few important things happen.
We’ll use the following code example to illustrate:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">plant_a_tree</span><span class="p">():</span>
    <span class="n">dig_the_hole_task</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">create_task</span><span class="p">(</span><span class="n">dig_the_hole</span><span class="p">())</span>
    <span class="k">await</span> <span class="n">dig_the_hole_task</span>

    <span class="c1"># Other instructions associated with planting a tree.</span>
    <span class="o">...</span>
</pre></div>
</div>
<p>In this example, imagine the event loop has passed control to the start of the
coroutine <code class="docutils literal notranslate"><span class="pre">plant_a_tree()</span></code>.
As seen above, the coroutine creates a task and then awaits it.
The <code class="docutils literal notranslate"><span class="pre">await</span> <span class="pre">dig_the_hole_task</span></code> instruction adds a callback (which will resume
<code class="docutils literal notranslate"><span class="pre">plant_a_tree()</span></code>) to the <code class="docutils literal notranslate"><span class="pre">dig_the_hole_task</span></code> object’s list of callbacks.
And then, the instruction cedes control to the event loop.
Some time later, the event loop will pass control to <code class="docutils literal notranslate"><span class="pre">dig_the_hole_task</span></code>
and the task will finish whatever it needs to do.
Once the task finishes, it will add its various callbacks to the event loop,
in this case, a call to resume <code class="docutils literal notranslate"><span class="pre">plant_a_tree()</span></code>.</p>
<p>Generally speaking, when the awaited task finishes (<code class="docutils literal notranslate"><span class="pre">dig_the_hole_task</span></code>),
the original task or coroutine (<code class="docutils literal notranslate"><span class="pre">plant_a_tree()</span></code>) is added back to the event
loop’s to-do list to be resumed.</p>
<p>This is a basic, yet reliable mental model.
In practice, the control handoffs are slightly more complex, but not by much.
In part 2, we’ll walk through the details that make this possible.</p>
</section>
<section id="awaiting-coroutines">
<h4>Awaiting coroutines<a class="headerlink" href="#awaiting-coroutines" title="Link to this heading">¶</a></h4>
<p><strong>Unlike tasks, awaiting a coroutine does not hand control back to the event
loop!</strong>
Wrapping a coroutine in a task first, then awaiting that would cede
control.
The behavior of <code class="docutils literal notranslate"><span class="pre">await</span> <span class="pre">coroutine</span></code> is effectively the same as invoking a
regular, synchronous Python function.
Consider this program:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">asyncio</span>

<span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">coro_a</span><span class="p">():</span>
   <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;I am coro_a(). Hi!&quot;</span><span class="p">)</span>

<span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">coro_b</span><span class="p">():</span>
   <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;I am coro_b(). I sure hope no one hogs the event loop...&quot;</span><span class="p">)</span>

<span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">main</span><span class="p">():</span>
   <span class="n">task_b</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">create_task</span><span class="p">(</span><span class="n">coro_b</span><span class="p">())</span>
   <span class="n">num_repeats</span> <span class="o">=</span> <span class="mi">3</span>
   <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">num_repeats</span><span class="p">):</span>
      <span class="k">await</span> <span class="n">coro_a</span><span class="p">()</span>
   <span class="k">await</span> <span class="n">task_b</span>

<span class="n">asyncio</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">main</span><span class="p">())</span>
</pre></div>
</div>
<p>The first statement in the coroutine <code class="docutils literal notranslate"><span class="pre">main()</span></code> creates <code class="docutils literal notranslate"><span class="pre">task_b</span></code> and schedules
it for execution via the event loop.
Then, <code class="docutils literal notranslate"><span class="pre">coro_a()</span></code> is repeatedly awaited. Control never cedes to the
event loop, which is why we see the output of all three <code class="docutils literal notranslate"><span class="pre">coro_a()</span></code>
invocations before <code class="docutils literal notranslate"><span class="pre">coro_b()</span></code>’s output:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>I am coro_a(). Hi!
I am coro_a(). Hi!
I am coro_a(). Hi!
I am coro_b(). I sure hope no one hogs the event loop...
</pre></div>
</div>
<p>If we change <code class="docutils literal notranslate"><span class="pre">await</span> <span class="pre">coro_a()</span></code> to <code class="docutils literal notranslate"><span class="pre">await</span> <span class="pre">asyncio.create_task(coro_a())</span></code>, the
behavior changes.
The coroutine <code class="docutils literal notranslate"><span class="pre">main()</span></code> cedes control to the event loop with that statement.
The event loop then proceeds through its backlog of work, calling <code class="docutils literal notranslate"><span class="pre">task_b</span></code>
and then the task which wraps <code class="docutils literal notranslate"><span class="pre">coro_a()</span></code> before resuming the coroutine
<code class="docutils literal notranslate"><span class="pre">main()</span></code>.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>I am coro_b(). I sure hope no one hogs the event loop...
I am coro_a(). Hi!
I am coro_a(). Hi!
I am coro_a(). Hi!
</pre></div>
</div>
<p>This behavior of <code class="docutils literal notranslate"><span class="pre">await</span> <span class="pre">coroutine</span></code> can trip a lot of people up!
That example highlights how using only <code class="docutils literal notranslate"><span class="pre">await</span> <span class="pre">coroutine</span></code> could
unintentionally hog control from other tasks and effectively stall the event
loop.
<a class="reference internal" href="../library/asyncio-runner.html#asyncio.run" title="asyncio.run"><code class="xref py py-func docutils literal notranslate"><span class="pre">asyncio.run()</span></code></a> can help you detect such occurrences via the
<code class="docutils literal notranslate"><span class="pre">debug=True</span></code> flag, which enables
<a class="reference internal" href="../library/asyncio-dev.html#asyncio-debug-mode"><span class="std std-ref">debug mode</span></a>.
Among other things, it will log any coroutines that monopolize execution for
100ms or longer.</p>
<p>The design intentionally trades off some conceptual clarity around usage of
<code class="docutils literal notranslate"><span class="pre">await</span></code> for improved performance.
Each time a task is awaited, control needs to be passed all the way up the
call stack to the event loop.
Then, the event loop needs to manage its internal state and work through
its processing logic to resume the next job.
That might sound minor, but in a large program with many <code class="docutils literal notranslate"><span class="pre">await</span></code>s, that
overhead can add up to a non-negligible performance drag.</p>
</section>
</section>
</section>
<section id="a-conceptual-overview-part-2-the-nuts-and-bolts">
<h2>A conceptual overview part 2: the nuts and bolts<a class="headerlink" href="#a-conceptual-overview-part-2-the-nuts-and-bolts" title="Link to this heading">¶</a></h2>
<p>Part 2 goes into detail on the mechanisms <code class="xref py py-mod docutils literal notranslate"><span class="pre">asyncio</span></code> uses to manage
control flow.
This is where the magic happens.
You’ll come away from this section knowing what <code class="docutils literal notranslate"><span class="pre">await</span></code> does behind the scenes
and how to make your own asynchronous operators.</p>
<section id="the-inner-workings-of-coroutines">
<h3>The inner workings of coroutines<a class="headerlink" href="#the-inner-workings-of-coroutines" title="Link to this heading">¶</a></h3>
<p><code class="xref py py-mod docutils literal notranslate"><span class="pre">asyncio</span></code> leverages four components of Python to pass
around control.</p>
<p><a class="reference internal" href="../reference/expressions.html#generator.send" title="generator.send"><code class="xref py py-meth docutils literal notranslate"><span class="pre">coroutine.send(arg)</span></code></a> is the method used to start or
resume a coroutine.
If the coroutine was paused and is now being resumed, the argument <code class="docutils literal notranslate"><span class="pre">arg</span></code>
will be sent in as the return value of the <code class="docutils literal notranslate"><span class="pre">yield</span></code> statement which originally
paused it.
If the coroutine is being used for the first time (as opposed to being resumed),
<code class="docutils literal notranslate"><span class="pre">arg</span></code> must be <code class="docutils literal notranslate"><span class="pre">None</span></code>.</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="linenos"> 1</span><span class="k">class</span><span class="w"> </span><span class="nc">Rock</span><span class="p">:</span>
<span class="linenos"> 2</span>    <span class="k">def</span><span class="w"> </span><span class="fm">__await__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="linenos"> 3</span>        <span class="n">value_sent_in</span> <span class="o">=</span> <span class="k">yield</span> <span class="mi">7</span>
<span class="linenos"> 4</span>        <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Rock.__await__ resuming with value: </span><span class="si">{</span><span class="n">value_sent_in</span><span class="si">}</span><span class="s2">.&quot;</span><span class="p">)</span>
<span class="linenos"> 5</span>        <span class="k">return</span> <span class="n">value_sent_in</span>
<span class="linenos"> 6</span>
<span class="linenos"> 7</span><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">main</span><span class="p">():</span>
<span class="linenos"> 8</span>    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Beginning coroutine main().&quot;</span><span class="p">)</span>
<span class="linenos"> 9</span>    <span class="n">rock</span> <span class="o">=</span> <span class="n">Rock</span><span class="p">()</span>
<span class="linenos">10</span>    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Awaiting rock...&quot;</span><span class="p">)</span>
<span class="linenos">11</span>    <span class="n">value_from_rock</span> <span class="o">=</span> <span class="k">await</span> <span class="n">rock</span>
<span class="linenos">12</span>    <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Coroutine received value: </span><span class="si">{</span><span class="n">value_from_rock</span><span class="si">}</span><span class="s2"> from rock.&quot;</span><span class="p">)</span>
<span class="linenos">13</span>    <span class="k">return</span> <span class="mi">23</span>
<span class="linenos">14</span>
<span class="linenos">15</span><span class="n">coroutine</span> <span class="o">=</span> <span class="n">main</span><span class="p">()</span>
<span class="linenos">16</span><span class="n">intermediate_result</span> <span class="o">=</span> <span class="n">coroutine</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="kc">None</span><span class="p">)</span>
<span class="linenos">17</span><span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Coroutine paused and returned intermediate value: </span><span class="si">{</span><span class="n">intermediate_result</span><span class="si">}</span><span class="s2">.&quot;</span><span class="p">)</span>
<span class="linenos">18</span>
<span class="linenos">19</span><span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Resuming coroutine and sending in value: 42.&quot;</span><span class="p">)</span>
<span class="linenos">20</span><span class="k">try</span><span class="p">:</span>
<span class="linenos">21</span>    <span class="n">coroutine</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="mi">42</span><span class="p">)</span>
<span class="linenos">22</span><span class="k">except</span> <span class="ne">StopIteration</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="linenos">23</span>    <span class="n">returned_value</span> <span class="o">=</span> <span class="n">e</span><span class="o">.</span><span class="n">value</span>
<span class="linenos">24</span><span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Coroutine main() finished and provided value: </span><span class="si">{</span><span class="n">returned_value</span><span class="si">}</span><span class="s2">.&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p><a class="reference internal" href="../reference/expressions.html#yieldexpr"><span class="std std-ref">yield</span></a>, as usual, pauses execution and returns control
to the caller.
In the example above, the <code class="docutils literal notranslate"><span class="pre">yield</span></code>, on line 3, is called by
<code class="docutils literal notranslate"><span class="pre">...</span> <span class="pre">=</span> <span class="pre">await</span> <span class="pre">rock</span></code> on line 11.
More broadly speaking, <code class="docutils literal notranslate"><span class="pre">await</span></code> calls the <a class="reference internal" href="../reference/datamodel.html#object.__await__" title="object.__await__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__await__()</span></code></a> method of
the given object.
<code class="docutils literal notranslate"><span class="pre">await</span></code> also does one more very special thing: it propagates (or “passes
along”) any <code class="docutils literal notranslate"><span class="pre">yield</span></code>s it receives up the call chain.
In this case, that’s back to <code class="docutils literal notranslate"><span class="pre">...</span> <span class="pre">=</span> <span class="pre">coroutine.send(None)</span></code> on line 16.</p>
<p>The coroutine is resumed via the <code class="docutils literal notranslate"><span class="pre">coroutine.send(42)</span></code> call on line 21.
The coroutine picks back up from where it <code class="docutils literal notranslate"><span class="pre">yield</span></code>ed (or paused) on line 3
and executes the remaining statements in its body.
When a coroutine finishes, it raises a <a class="reference internal" href="../library/exceptions.html#StopIteration" title="StopIteration"><code class="xref py py-exc docutils literal notranslate"><span class="pre">StopIteration</span></code></a> exception with the
return value attached in the <a class="reference internal" href="../library/exceptions.html#StopIteration.value" title="StopIteration.value"><code class="xref py py-attr docutils literal notranslate"><span class="pre">value</span></code></a> attribute.</p>
<p>That snippet produces this output:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>Beginning coroutine main().
Awaiting rock...
Coroutine paused and returned intermediate value: 7.
Resuming coroutine and sending in value: 42.
Rock.__await__ resuming with value: 42.
Coroutine received value: 42 from rock.
Coroutine main() finished and provided value: 23.
</pre></div>
</div>
<p>It’s worth pausing for a moment here and making sure you followed the various
ways that control flow and values were passed. A lot of important ideas were
covered and it’s worth ensuring your understanding is firm.</p>
<p>The only way to yield (or effectively cede control) from a coroutine is to
<code class="docutils literal notranslate"><span class="pre">await</span></code> an object that <code class="docutils literal notranslate"><span class="pre">yield</span></code>s in its <code class="docutils literal notranslate"><span class="pre">__await__</span></code> method.
That might sound odd to you. You might be thinking:</p>
<blockquote>
<div><p>1. What about a <code class="docutils literal notranslate"><span class="pre">yield</span></code> directly within the coroutine function? The
coroutine function becomes an
<a class="reference internal" href="../reference/expressions.html#asynchronous-generator-functions"><span class="std std-ref">async generator function</span></a>, a
different beast entirely.</p>
<p>2. What about a <a class="reference internal" href="../reference/expressions.html#yieldexpr"><span class="std std-ref">yield from</span></a> within the coroutine function to a (plain)
generator?
That causes the error: <code class="docutils literal notranslate"><span class="pre">SyntaxError:</span> <span class="pre">yield</span> <span class="pre">from</span> <span class="pre">not</span> <span class="pre">allowed</span> <span class="pre">in</span> <span class="pre">a</span> <span class="pre">coroutine.</span></code>
This was intentionally designed for the sake of simplicity – mandating only
one way of using coroutines.
Despite that, <code class="docutils literal notranslate"><span class="pre">yield</span> <span class="pre">from</span></code> and <code class="docutils literal notranslate"><span class="pre">await</span></code> effectively do the same thing.
Initially <code class="docutils literal notranslate"><span class="pre">yield</span></code> was barred as well, but was re-accepted to allow for
async generators.</p>
</div></blockquote>
</section>
<section id="futures">
<h3>Futures<a class="headerlink" href="#futures" title="Link to this heading">¶</a></h3>
<p>A <a class="reference internal" href="../library/asyncio-future.html#asyncio-future-obj"><span class="std std-ref">future</span></a> is an object meant to represent a
computation’s status and result.
The term is a nod to the idea of something still to come or not yet happened,
and the object is a way to keep an eye on that something.</p>
<p>A future has a few important attributes. One is its state, which can be either
“pending”, “cancelled”, or “done”.
Another is its result, which is set when the state transitions to done.
Unlike a coroutine, a future does not represent the actual computation to be
done; instead, it represents the status and result of that computation, kind of
like a status light (red, yellow, or green) or indicator.</p>
<p><a class="reference internal" href="../library/asyncio-task.html#asyncio.Task" title="asyncio.Task"><code class="xref py py-class docutils literal notranslate"><span class="pre">asyncio.Task</span></code></a> subclasses <a class="reference internal" href="../library/asyncio-future.html#asyncio.Future" title="asyncio.Future"><code class="xref py py-class docutils literal notranslate"><span class="pre">asyncio.Future</span></code></a> in order to gain
these various capabilities.
The prior section said tasks store a list of callbacks, which wasn’t entirely
accurate.
It’s actually the <code class="docutils literal notranslate"><span class="pre">Future</span></code> class that implements this logic, which <code class="docutils literal notranslate"><span class="pre">Task</span></code>
inherits.</p>
<p>Futures may also be used directly (not via tasks).
Tasks mark themselves as done when their coroutine is complete.
Futures are much more versatile and will be marked as done when you say so.
In this way, they’re the flexible interface for you to make your own conditions
for waiting and resuming.</p>
</section>
<section id="a-homemade-asyncio-sleep">
<h3>A homemade asyncio.sleep<a class="headerlink" href="#a-homemade-asyncio-sleep" title="Link to this heading">¶</a></h3>
<p>We’ll go through an example of how you could leverage a future to create your
own variant of asynchronous sleep (<code class="docutils literal notranslate"><span class="pre">async_sleep</span></code>) which mimics
<a class="reference internal" href="../library/asyncio-task.html#asyncio.sleep" title="asyncio.sleep"><code class="xref py py-func docutils literal notranslate"><span class="pre">asyncio.sleep()</span></code></a>.</p>
<p>This snippet registers a few tasks with the event loop and then awaits the task
created by <code class="docutils literal notranslate"><span class="pre">asyncio.create_task</span></code>, which wraps the <code class="docutils literal notranslate"><span class="pre">async_sleep(3)</span></code> coroutine.
We want that task to finish only after three seconds have elapsed, but without
preventing other tasks from running.</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">other_work</span><span class="p">():</span>
    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;I like work. Work work.&quot;</span><span class="p">)</span>

<span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">main</span><span class="p">():</span>
    <span class="c1"># Add a few other tasks to the event loop, so there&#x27;s something</span>
    <span class="c1"># to do while asynchronously sleeping.</span>
    <span class="n">work_tasks</span> <span class="o">=</span> <span class="p">[</span>
        <span class="n">asyncio</span><span class="o">.</span><span class="n">create_task</span><span class="p">(</span><span class="n">other_work</span><span class="p">()),</span>
        <span class="n">asyncio</span><span class="o">.</span><span class="n">create_task</span><span class="p">(</span><span class="n">other_work</span><span class="p">()),</span>
        <span class="n">asyncio</span><span class="o">.</span><span class="n">create_task</span><span class="p">(</span><span class="n">other_work</span><span class="p">())</span>
    <span class="p">]</span>
    <span class="nb">print</span><span class="p">(</span>
        <span class="s2">&quot;Beginning asynchronous sleep at time: &quot;</span>
        <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s2">&quot;%H:%M:%S&quot;</span><span class="p">)</span><span class="si">}</span><span class="s2">.&quot;</span>
    <span class="p">)</span>
    <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">create_task</span><span class="p">(</span><span class="n">async_sleep</span><span class="p">(</span><span class="mi">3</span><span class="p">))</span>
    <span class="nb">print</span><span class="p">(</span>
        <span class="s2">&quot;Done asynchronous sleep at time: &quot;</span>
        <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s2">&quot;%H:%M:%S&quot;</span><span class="p">)</span><span class="si">}</span><span class="s2">.&quot;</span>
    <span class="p">)</span>
    <span class="c1"># asyncio.gather effectively awaits each task in the collection.</span>
    <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">gather</span><span class="p">(</span><span class="o">*</span><span class="n">work_tasks</span><span class="p">)</span>
</pre></div>
</div>
<p>Below, we use a future to enable custom control over when that task will be
marked as done.
If <a class="reference internal" href="../library/asyncio-future.html#asyncio.Future.set_result" title="asyncio.Future.set_result"><code class="xref py py-meth docutils literal notranslate"><span class="pre">future.set_result()</span></code></a> (the method
responsible for marking that future as done) is never called, then this task
will never finish.
We’ve also enlisted the help of another task, which we’ll see in a moment, that
will monitor how much time has elapsed and, accordingly, call
<code class="docutils literal notranslate"><span class="pre">future.set_result()</span></code>.</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">async_sleep</span><span class="p">(</span><span class="n">seconds</span><span class="p">:</span> <span class="nb">float</span><span class="p">):</span>
    <span class="n">future</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">Future</span><span class="p">()</span>
    <span class="n">time_to_wake</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">+</span> <span class="n">seconds</span>
    <span class="c1"># Add the watcher-task to the event loop.</span>
    <span class="n">watcher_task</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">create_task</span><span class="p">(</span><span class="n">_sleep_watcher</span><span class="p">(</span><span class="n">future</span><span class="p">,</span> <span class="n">time_to_wake</span><span class="p">))</span>
    <span class="c1"># Block until the future is marked as done.</span>
    <span class="k">await</span> <span class="n">future</span>
</pre></div>
</div>
<p>Below, we use a rather bare <code class="docutils literal notranslate"><span class="pre">YieldToEventLoop()</span></code> object to <code class="docutils literal notranslate"><span class="pre">yield</span></code>
from its <code class="docutils literal notranslate"><span class="pre">__await__</span></code> method, ceding control to the event loop.
This is effectively the same as calling <code class="docutils literal notranslate"><span class="pre">asyncio.sleep(0)</span></code>, but this approach
offers more clarity, not to mention it’s somewhat cheating to use
<code class="docutils literal notranslate"><span class="pre">asyncio.sleep</span></code> when showcasing how to implement it!</p>
<p>As usual, the event loop cycles through its tasks, giving them control
and receiving control back when they pause or finish.
The <code class="docutils literal notranslate"><span class="pre">watcher_task</span></code>, which runs the coroutine <code class="docutils literal notranslate"><span class="pre">_sleep_watcher(...)</span></code>, will
be invoked once per full cycle of the event loop.
On each resumption, it’ll check the time and if not enough has elapsed, then
it’ll pause once again and hand control back to the event loop.
Once enough time has elapsed, <code class="docutils literal notranslate"><span class="pre">_sleep_watcher(...)</span></code>
marks the future as done and completes by exiting its
infinite <code class="docutils literal notranslate"><span class="pre">while</span></code> loop.
Given this helper task is only invoked once per cycle of the event loop,
you’d be correct to note that this asynchronous sleep will sleep <em>at least</em>
three seconds, rather than exactly three seconds.
Note this is also true of <code class="docutils literal notranslate"><span class="pre">asyncio.sleep</span></code>.</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span><span class="w"> </span><span class="nc">YieldToEventLoop</span><span class="p">:</span>
    <span class="k">def</span><span class="w"> </span><span class="fm">__await__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">yield</span>

<span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">_sleep_watcher</span><span class="p">(</span><span class="n">future</span><span class="p">,</span> <span class="n">time_to_wake</span><span class="p">):</span>
    <span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
        <span class="k">if</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">&gt;=</span> <span class="n">time_to_wake</span><span class="p">:</span>
            <span class="c1"># This marks the future as done.</span>
            <span class="n">future</span><span class="o">.</span><span class="n">set_result</span><span class="p">(</span><span class="kc">None</span><span class="p">)</span>
            <span class="k">break</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">await</span> <span class="n">YieldToEventLoop</span><span class="p">()</span>
</pre></div>
</div>
<p>Here is the full program’s output:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>$ python custom-async-sleep.py
Beginning asynchronous sleep at time: 14:52:22.
I like work. Work work.
I like work. Work work.
I like work. Work work.
Done asynchronous sleep at time: 14:52:25.
</pre></div>
</div>
<p>You might feel this implementation of asynchronous sleep was unnecessarily
convoluted.
And, well, it was.
The example was meant to showcase the versatility of futures with a simple
example that could be mimicked for more complex needs.
For reference, you could implement it without futures, like so:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">simpler_async_sleep</span><span class="p">(</span><span class="n">seconds</span><span class="p">):</span>
    <span class="n">time_to_wake</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">+</span> <span class="n">seconds</span>
    <span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
        <span class="k">if</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">&gt;=</span> <span class="n">time_to_wake</span><span class="p">:</span>
            <span class="k">return</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">await</span> <span class="n">YieldToEventLoop</span><span class="p">()</span>
</pre></div>
</div>
<p>But that’s all for now. Hopefully you’re ready to more confidently dive into
some async programming or check out advanced topics in the
<a class="reference internal" href="../library/asyncio.html#module-asyncio" title="asyncio: Asynchronous I/O."><code class="xref py py-mod docutils literal notranslate"><span class="pre">rest</span> <span class="pre">of</span> <span class="pre">the</span> <span class="pre">documentation</span></code></a>.</p>
</section>
</section>
</section>


            <div class="clearer"></div>
          </div>
        </div>
      </div>
      <div class="sphinxsidebar" role="navigation" aria-label="Main">
        <div class="sphinxsidebarwrapper">
  <div>
    <h3><a href="../contents.html">Table of Contents</a></h3>
    <ul>
<li><a class="reference internal" href="#">A conceptual overview of <code class="xref py py-mod docutils literal notranslate"><span class="pre">asyncio</span></code></a><ul>
<li><a class="reference internal" href="#a-conceptual-overview-part-1-the-high-level">A conceptual overview part 1: the high-level</a><ul>
<li><a class="reference internal" href="#event-loop">Event loop</a></li>
<li><a class="reference internal" href="#asynchronous-functions-and-coroutines">Asynchronous functions and coroutines</a></li>
<li><a class="reference internal" href="#tasks">Tasks</a></li>
<li><a class="reference internal" href="#await">await</a><ul>
<li><a class="reference internal" href="#awaiting-tasks">Awaiting tasks</a></li>
<li><a class="reference internal" href="#awaiting-coroutines">Awaiting coroutines</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#a-conceptual-overview-part-2-the-nuts-and-bolts">A conceptual overview part 2: the nuts and bolts</a><ul>
<li><a class="reference internal" href="#the-inner-workings-of-coroutines">The inner workings of coroutines</a></li>
<li><a class="reference internal" href="#futures">Futures</a></li>
<li><a class="reference internal" href="#a-homemade-asyncio-sleep">A homemade asyncio.sleep</a></li>
</ul>
</li>
</ul>
</li>
</ul>

  </div>
  <div>
    <h4>Previous topic</h4>
    <p class="topless"><a href="index.html"
                          title="previous chapter">Python HOWTOs</a></p>
  </div>
  <div>
    <h4>Next topic</h4>
    <p class="topless"><a href="cporting.html"
                          title="next chapter">Porting Extension Modules to Python 3</a></p>
  </div>
  <script>
    document.addEventListener('DOMContentLoaded', () => {
        const title = document.querySelector('meta[property="og:title"]').content;
        const elements = document.querySelectorAll('.improvepage');
        const pageurl = window.location.href.split('?')[0];
        elements.forEach(element => {
            const url = new URL(element.href.split('?')[0].replace("-nojs", ""));
            url.searchParams.set('pagetitle', title);
            url.searchParams.set('pageurl', pageurl);
            url.searchParams.set('pagesource', "howto/a-conceptual-overview-of-asyncio.rst");
            element.href = url.toString();
        });
    });
  </script>
  <div role="note" aria-label="source link">
    <h3>This page</h3>
    <ul class="this-page-menu">
      <li><a href="../bugs.html">Report a bug</a></li>
      <li><a class="improvepage" href="../improve-page-nojs.html">Improve this page</a></li>
      <li>
        <a href="https://github.com/python/cpython/blob/main/Doc/howto/a-conceptual-overview-of-asyncio.rst?plain=1"
            rel="nofollow">Show source
        </a>
      </li>
      
    </ul>
  </div>
        </div>
<div id="sidebarbutton" title="Collapse sidebar">
<span>«</span>
</div>

      </div>
      <div class="clearer"></div>
    </div>  
    <div class="related" role="navigation" aria-label="Related">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex.html" title="General Index"
             >index</a></li>
        <li class="right" >
          <a href="../py-modindex.html" title="Python Module Index"
             >modules</a> |</li>
        <li class="right" >
          <a href="cporting.html" title="Porting Extension Modules to Python 3"
             >next</a> |</li>
        <li class="right" >
          <a href="index.html" title="Python HOWTOs"
             >previous</a> |</li>

          <li><img src="../_static/py.svg" alt="Python logo" style="vertical-align: middle; margin-top: -1px"></li>
          <li><a href="https://www.python.org/">Python</a> &#187;</li>
          <li class="switchers">
            <div class="language_switcher_placeholder"></div>
            <div class="version_switcher_placeholder"></div>
          </li>
          <li>
              
          </li>
    <li id="cpython-language-and-version">
      <a href="../index.html">3.15.0rc1 Documentation</a> &#187;
    </li>

          <li class="nav-item nav-item-1"><a href="index.html" >Python HOWTOs</a> &#187;</li>
        <li class="nav-item nav-item-this"><a href="">A conceptual overview of <code class="xref py py-mod docutils literal notranslate"><span class="pre">asyncio</span></code></a></li>
                <li class="right">
                    

    <div class="inline-search" role="search">
        <form class="inline-search" action="../search.html" method="get">
          <input placeholder="Quick search" aria-label="Quick search" type="search" name="q" id="search-box">
          <input type="submit" value="Go">
        </form>
    </div>
                     |
                </li>
            <li class="right">
<label class="theme-selector-label">
    Theme
    <select class="theme-selector" oninput="activateTheme(this.value)">
        <option value="auto" selected>Auto</option>
        <option value="light">Light</option>
        <option value="dark">Dark</option>
    </select>
</label> |</li>
            
      </ul>
    </div>  
    <div class="footer">
    &copy; <a href="../copyright.html">Copyright</a> 2001 Python Software Foundation.
    <br>
    This page is licensed under the Python Software Foundation License Version 2.
    <br>
    Examples, recipes, and other code in the documentation are additionally licensed under the Zero Clause BSD License.
    <br>
    
      See <a href="/license.html">History and License</a> for more information.<br>
    
    
    <br>

    The Python Software Foundation is a non-profit corporation.
<a href="https://www.python.org/psf/donations/">Please donate.</a>
<br>
    <br>
      Last updated on Aug 04, 2026 (11:13 UTC).
    
      <a href="/bugs.html">Found a bug</a>?
    
    <br>

    Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 8.2.3.
    </div>

  </body>
</html>

Youez - 2016 - github.com/yon3zu
LinuXploit