549 lines
43 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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="timer file descriptor HOWTO" />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://docs.python.org/3/howto/timerfd.html" />
<meta property="og:site_name" content="Python documentation" />
<meta property="og:description" content="Release, 1.13,. This HOWTO discusses Pythons support for the linux timer file descriptor. Examples: The following example shows how to use a timer file descriptor to execute a function twice a sec..." />
<meta property="og:image" content="https://docs.python.org/3/_static/og-image.png" />
<meta property="og:image:alt" content="Python documentation" />
<meta name="description" content="Release, 1.13,. This HOWTO discusses Pythons support for the linux timer file descriptor. Examples: The following example shows how to use a timer file descriptor to execute a function twice a sec..." />
<meta property="og:image:width" content="200">
<meta property="og:image:height" content="200">
<meta name="theme-color" content="#3776ab">
<title>timer file descriptor HOWTO &#8212; Python 3.13.3 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/pydoctheme.css?v=23252803" />
<link id="pygments_dark_css" media="(prefers-color-scheme: dark)" rel="stylesheet" type="text/css" href="../_static/pygments_dark.css?v=5349f25f" />
<script src="../_static/documentation_options.js?v=5d57ca2d"></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.13.3 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="The Python 2.3 Method Resolution Order" href="mro.html" />
<link rel="prev" title="Isolating Extension Modules" href="isolating-extensions.html" />
<link rel="canonical" href="https://docs.python.org/3/howto/timerfd.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="#">timer file descriptor HOWTO</a><ul>
<li><a class="reference internal" href="#examples">Examples</a></li>
</ul>
</li>
</ul>
</div>
<div>
<h4>Previous topic</h4>
<p class="topless"><a href="isolating-extensions.html"
title="previous chapter">Isolating Extension Modules</a></p>
</div>
<div>
<h4>Next topic</h4>
<p class="topless"><a href="mro.html"
title="next chapter">The Python 2.3 Method Resolution Order</a></p>
</div>
<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 href="https://github.com/python/cpython/blob/main/Doc/howto/timerfd.rst"
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="mro.html" title="The Python 2.3 Method Resolution Order"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="isolating-extensions.html" title="Isolating Extension Modules"
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.13.3 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="">timer file descriptor HOWTO</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="timer-file-descriptor-howto">
<span id="timerfd-howto"></span><h1>timer file descriptor HOWTO<a class="headerlink" href="#timer-file-descriptor-howto" title="Link to this heading"></a></h1>
<dl class="field-list simple">
<dt class="field-odd">Release<span class="colon">:</span></dt>
<dd class="field-odd"><p>1.13</p>
</dd>
</dl>
<p>This HOWTO discusses Pythons support for the linux timer file descriptor.</p>
<section id="examples">
<h2>Examples<a class="headerlink" href="#examples" title="Link to this heading"></a></h2>
<p>The following example shows how to use a timer file descriptor
to execute a function twice a second:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># Practical scripts should use really use a non-blocking timer,</span>
<span class="c1"># we use a blocking timer here for simplicity.</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">os</span><span class="o">,</span><span class="w"> </span><span class="nn">time</span>
<span class="c1"># Create the timer file descriptor</span>
<span class="n">fd</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">timerfd_create</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">CLOCK_REALTIME</span><span class="p">)</span>
<span class="c1"># Start the timer in 1 second, with an interval of half a second</span>
<span class="n">os</span><span class="o">.</span><span class="n">timerfd_settime</span><span class="p">(</span><span class="n">fd</span><span class="p">,</span> <span class="n">initial</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">interval</span><span class="o">=</span><span class="mf">0.5</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="c1"># Process timer events four times.</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="mi">4</span><span class="p">):</span>
<span class="c1"># read() will block until the timer expires</span>
<span class="n">_</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">fd</span><span class="p">,</span> <span class="mi">8</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Timer expired&quot;</span><span class="p">)</span>
<span class="k">finally</span><span class="p">:</span>
<span class="c1"># Remember to close the timer file descriptor!</span>
<span class="n">os</span><span class="o">.</span><span class="n">close</span><span class="p">(</span><span class="n">fd</span><span class="p">)</span>
</pre></div>
</div>
<p>To avoid the precision loss caused by the <a class="reference internal" href="../library/functions.html#float" title="float"><code class="xref py py-class docutils literal notranslate"><span class="pre">float</span></code></a> type,
timer file descriptors allow specifying initial expiration and interval
in integer nanoseconds with <code class="docutils literal notranslate"><span class="pre">_ns</span></code> variants of the functions.</p>
<p>This example shows how <a class="reference internal" href="../library/select.html#select.epoll" title="select.epoll"><code class="xref py py-func docutils literal notranslate"><span class="pre">epoll()</span></code></a> can be used with timer file
descriptors to wait until the file descriptor is ready for reading:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">os</span><span class="o">,</span><span class="w"> </span><span class="nn">time</span><span class="o">,</span><span class="w"> </span><span class="nn">select</span><span class="o">,</span><span class="w"> </span><span class="nn">socket</span><span class="o">,</span><span class="w"> </span><span class="nn">sys</span>
<span class="c1"># Create an epoll object</span>
<span class="n">ep</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">epoll</span><span class="p">()</span>
<span class="c1"># In this example, use loopback address to send &quot;stop&quot; command to the server.</span>
<span class="c1">#</span>
<span class="c1"># $ telnet 127.0.0.1 1234</span>
<span class="c1"># Trying 127.0.0.1...</span>
<span class="c1"># Connected to 127.0.0.1.</span>
<span class="c1"># Escape character is &#39;^]&#39;.</span>
<span class="c1"># stop</span>
<span class="c1"># Connection closed by foreign host.</span>
<span class="c1">#</span>
<span class="n">sock</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">socket</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">AF_INET</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">SOCK_STREAM</span><span class="p">)</span>
<span class="n">sock</span><span class="o">.</span><span class="n">bind</span><span class="p">((</span><span class="s2">&quot;127.0.0.1&quot;</span><span class="p">,</span> <span class="mi">1234</span><span class="p">))</span>
<span class="n">sock</span><span class="o">.</span><span class="n">setblocking</span><span class="p">(</span><span class="kc">False</span><span class="p">)</span>
<span class="n">sock</span><span class="o">.</span><span class="n">listen</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">ep</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="n">sock</span><span class="p">,</span> <span class="n">select</span><span class="o">.</span><span class="n">EPOLLIN</span><span class="p">)</span>
<span class="c1"># Create timer file descriptors in non-blocking mode.</span>
<span class="n">num</span> <span class="o">=</span> <span class="mi">3</span>
<span class="n">fds</span> <span class="o">=</span> <span class="p">[]</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</span><span class="p">):</span>
<span class="n">fd</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">timerfd_create</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">CLOCK_REALTIME</span><span class="p">,</span> <span class="n">flags</span><span class="o">=</span><span class="n">os</span><span class="o">.</span><span class="n">TFD_NONBLOCK</span><span class="p">)</span>
<span class="n">fds</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">fd</span><span class="p">)</span>
<span class="c1"># Register the timer file descriptor for read events</span>
<span class="n">ep</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="n">fd</span><span class="p">,</span> <span class="n">select</span><span class="o">.</span><span class="n">EPOLLIN</span><span class="p">)</span>
<span class="c1"># Start the timer with os.timerfd_settime_ns() in nanoseconds.</span>
<span class="c1"># Timer 1 fires every 0.25 seconds; timer 2 every 0.5 seconds; etc</span>
<span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">fd</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">fds</span><span class="p">,</span> <span class="n">start</span><span class="o">=</span><span class="mi">1</span><span class="p">):</span>
<span class="n">one_sec_in_nsec</span> <span class="o">=</span> <span class="mi">10</span><span class="o">**</span><span class="mi">9</span>
<span class="n">i</span> <span class="o">=</span> <span class="n">i</span> <span class="o">*</span> <span class="n">one_sec_in_nsec</span>
<span class="n">os</span><span class="o">.</span><span class="n">timerfd_settime_ns</span><span class="p">(</span><span class="n">fd</span><span class="p">,</span> <span class="n">initial</span><span class="o">=</span><span class="n">i</span><span class="o">//</span><span class="mi">4</span><span class="p">,</span> <span class="n">interval</span><span class="o">=</span><span class="n">i</span><span class="o">//</span><span class="mi">4</span><span class="p">)</span>
<span class="n">timeout</span> <span class="o">=</span> <span class="mi">3</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">conn</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">is_active</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">while</span> <span class="n">is_active</span><span class="p">:</span>
<span class="c1"># Wait for the timer to expire for 3 seconds.</span>
<span class="c1"># epoll.poll() returns a list of (fd, event) pairs.</span>
<span class="c1"># fd is a file descriptor.</span>
<span class="c1"># sock and conn[=returned value of socket.accept()] are socket objects, not file descriptors.</span>
<span class="c1"># So use sock.fileno() and conn.fileno() to get the file descriptors.</span>
<span class="n">events</span> <span class="o">=</span> <span class="n">ep</span><span class="o">.</span><span class="n">poll</span><span class="p">(</span><span class="n">timeout</span><span class="p">)</span>
<span class="c1"># If more than one timer file descriptors are ready for reading at once,</span>
<span class="c1"># epoll.poll() returns a list of (fd, event) pairs.</span>
<span class="c1">#</span>
<span class="c1"># In this example settings,</span>
<span class="c1"># 1st timer fires every 0.25 seconds in 0.25 seconds. (0.25, 0.5, 0.75, 1.0, ...)</span>
<span class="c1"># 2nd timer every 0.5 seconds in 0.5 seconds. (0.5, 1.0, 1.5, 2.0, ...)</span>
<span class="c1"># 3rd timer every 0.75 seconds in 0.75 seconds. (0.75, 1.5, 2.25, 3.0, ...)</span>
<span class="c1">#</span>
<span class="c1"># In 0.25 seconds, only 1st timer fires.</span>
<span class="c1"># In 0.5 seconds, 1st timer and 2nd timer fires at once.</span>
<span class="c1"># In 0.75 seconds, 1st timer and 3rd timer fires at once.</span>
<span class="c1"># In 1.5 seconds, 1st timer, 2nd timer and 3rd timer fires at once.</span>
<span class="c1">#</span>
<span class="c1"># If a timer file descriptor is signaled more than once since</span>
<span class="c1"># the last os.read() call, os.read() returns the number of signaled</span>
<span class="c1"># as host order of class bytes.</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Signaled events=</span><span class="si">{</span><span class="n">events</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">for</span> <span class="n">fd</span><span class="p">,</span> <span class="n">event</span> <span class="ow">in</span> <span class="n">events</span><span class="p">:</span>
<span class="k">if</span> <span class="n">event</span> <span class="o">&amp;</span> <span class="n">select</span><span class="o">.</span><span class="n">EPOLLIN</span><span class="p">:</span>
<span class="k">if</span> <span class="n">fd</span> <span class="o">==</span> <span class="n">sock</span><span class="o">.</span><span class="n">fileno</span><span class="p">():</span>
<span class="c1"># Check if there is a connection request.</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Accepting connection </span><span class="si">{</span><span class="n">fd</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="n">conn</span><span class="p">,</span> <span class="n">addr</span> <span class="o">=</span> <span class="n">sock</span><span class="o">.</span><span class="n">accept</span><span class="p">()</span>
<span class="n">conn</span><span class="o">.</span><span class="n">setblocking</span><span class="p">(</span><span class="kc">False</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Accepted connection </span><span class="si">{</span><span class="n">conn</span><span class="si">}</span><span class="s2"> from </span><span class="si">{</span><span class="n">addr</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="n">ep</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="n">select</span><span class="o">.</span><span class="n">EPOLLIN</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">conn</span> <span class="ow">and</span> <span class="n">fd</span> <span class="o">==</span> <span class="n">conn</span><span class="o">.</span><span class="n">fileno</span><span class="p">():</span>
<span class="c1"># Check if there is data to read.</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Reading data </span><span class="si">{</span><span class="n">fd</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">conn</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">1024</span><span class="p">)</span>
<span class="k">if</span> <span class="n">data</span><span class="p">:</span>
<span class="c1"># You should catch UnicodeDecodeError exception for safety.</span>
<span class="n">cmd</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">decode</span><span class="p">()</span>
<span class="k">if</span> <span class="n">cmd</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;stop&quot;</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Stopping server&quot;</span><span class="p">)</span>
<span class="n">is_active</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">else</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Unknown command: </span><span class="si">{</span><span class="n">cmd</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># No more data, close connection</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Closing connection </span><span class="si">{</span><span class="n">fd</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="n">ep</span><span class="o">.</span><span class="n">unregister</span><span class="p">(</span><span class="n">conn</span><span class="p">)</span>
<span class="n">conn</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="n">conn</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">elif</span> <span class="n">fd</span> <span class="ow">in</span> <span class="n">fds</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Reading timer </span><span class="si">{</span><span class="n">fd</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="n">count</span> <span class="o">=</span> <span class="nb">int</span><span class="o">.</span><span class="n">from_bytes</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">fd</span><span class="p">,</span> <span class="mi">8</span><span class="p">),</span> <span class="n">byteorder</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">byteorder</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Timer </span><span class="si">{</span><span class="n">fds</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="n">fd</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="si">}</span><span class="s2"> expired </span><span class="si">{</span><span class="n">count</span><span class="si">}</span><span class="s2"> times&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Unknown file descriptor </span><span class="si">{</span><span class="n">fd</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">finally</span><span class="p">:</span>
<span class="k">for</span> <span class="n">fd</span> <span class="ow">in</span> <span class="n">fds</span><span class="p">:</span>
<span class="n">ep</span><span class="o">.</span><span class="n">unregister</span><span class="p">(</span><span class="n">fd</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">close</span><span class="p">(</span><span class="n">fd</span><span class="p">)</span>
<span class="n">ep</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</pre></div>
</div>
<p>This example shows how <a class="reference internal" href="../library/select.html#select.select" title="select.select"><code class="xref py py-func docutils literal notranslate"><span class="pre">select()</span></code></a> can be used with timer file
descriptors to wait until the file descriptor is ready for reading:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">os</span><span class="o">,</span><span class="w"> </span><span class="nn">time</span><span class="o">,</span><span class="w"> </span><span class="nn">select</span><span class="o">,</span><span class="w"> </span><span class="nn">socket</span><span class="o">,</span><span class="w"> </span><span class="nn">sys</span>
<span class="c1"># In this example, use loopback address to send &quot;stop&quot; command to the server.</span>
<span class="c1">#</span>
<span class="c1"># $ telnet 127.0.0.1 1234</span>
<span class="c1"># Trying 127.0.0.1...</span>
<span class="c1"># Connected to 127.0.0.1.</span>
<span class="c1"># Escape character is &#39;^]&#39;.</span>
<span class="c1"># stop</span>
<span class="c1"># Connection closed by foreign host.</span>
<span class="c1">#</span>
<span class="n">sock</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">socket</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">AF_INET</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">SOCK_STREAM</span><span class="p">)</span>
<span class="n">sock</span><span class="o">.</span><span class="n">bind</span><span class="p">((</span><span class="s2">&quot;127.0.0.1&quot;</span><span class="p">,</span> <span class="mi">1234</span><span class="p">))</span>
<span class="n">sock</span><span class="o">.</span><span class="n">setblocking</span><span class="p">(</span><span class="kc">False</span><span class="p">)</span>
<span class="n">sock</span><span class="o">.</span><span class="n">listen</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="c1"># Create timer file descriptors in non-blocking mode.</span>
<span class="n">num</span> <span class="o">=</span> <span class="mi">3</span>
<span class="n">fds</span> <span class="o">=</span> <span class="p">[</span><span class="n">os</span><span class="o">.</span><span class="n">timerfd_create</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">CLOCK_REALTIME</span><span class="p">,</span> <span class="n">flags</span><span class="o">=</span><span class="n">os</span><span class="o">.</span><span class="n">TFD_NONBLOCK</span><span class="p">)</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</span><span class="p">)]</span>
<span class="n">select_fds</span> <span class="o">=</span> <span class="n">fds</span> <span class="o">+</span> <span class="p">[</span><span class="n">sock</span><span class="p">]</span>
<span class="c1"># Start the timers with os.timerfd_settime() in seconds.</span>
<span class="c1"># Timer 1 fires every 0.25 seconds; timer 2 every 0.5 seconds; etc</span>
<span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">fd</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">fds</span><span class="p">,</span> <span class="n">start</span><span class="o">=</span><span class="mi">1</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">timerfd_settime</span><span class="p">(</span><span class="n">fd</span><span class="p">,</span> <span class="n">initial</span><span class="o">=</span><span class="n">i</span><span class="o">/</span><span class="mi">4</span><span class="p">,</span> <span class="n">interval</span><span class="o">=</span><span class="n">i</span><span class="o">/</span><span class="mi">4</span><span class="p">)</span>
<span class="n">timeout</span> <span class="o">=</span> <span class="mi">3</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">conn</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">is_active</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">while</span> <span class="n">is_active</span><span class="p">:</span>
<span class="c1"># Wait for the timer to expire for 3 seconds.</span>
<span class="c1"># select.select() returns a list of file descriptors or objects.</span>
<span class="n">rfd</span><span class="p">,</span> <span class="n">wfd</span><span class="p">,</span> <span class="n">xfd</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">select</span><span class="p">(</span><span class="n">select_fds</span><span class="p">,</span> <span class="n">select_fds</span><span class="p">,</span> <span class="n">select_fds</span><span class="p">,</span> <span class="n">timeout</span><span class="p">)</span>
<span class="k">for</span> <span class="n">fd</span> <span class="ow">in</span> <span class="n">rfd</span><span class="p">:</span>
<span class="k">if</span> <span class="n">fd</span> <span class="o">==</span> <span class="n">sock</span><span class="p">:</span>
<span class="c1"># Check if there is a connection request.</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Accepting connection </span><span class="si">{</span><span class="n">fd</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="n">conn</span><span class="p">,</span> <span class="n">addr</span> <span class="o">=</span> <span class="n">sock</span><span class="o">.</span><span class="n">accept</span><span class="p">()</span>
<span class="n">conn</span><span class="o">.</span><span class="n">setblocking</span><span class="p">(</span><span class="kc">False</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Accepted connection </span><span class="si">{</span><span class="n">conn</span><span class="si">}</span><span class="s2"> from </span><span class="si">{</span><span class="n">addr</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="n">select_fds</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">conn</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">conn</span> <span class="ow">and</span> <span class="n">fd</span> <span class="o">==</span> <span class="n">conn</span><span class="p">:</span>
<span class="c1"># Check if there is data to read.</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Reading data </span><span class="si">{</span><span class="n">fd</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">conn</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">1024</span><span class="p">)</span>
<span class="k">if</span> <span class="n">data</span><span class="p">:</span>
<span class="c1"># You should catch UnicodeDecodeError exception for safety.</span>
<span class="n">cmd</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">decode</span><span class="p">()</span>
<span class="k">if</span> <span class="n">cmd</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;stop&quot;</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Stopping server&quot;</span><span class="p">)</span>
<span class="n">is_active</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">else</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Unknown command: </span><span class="si">{</span><span class="n">cmd</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># No more data, close connection</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Closing connection </span><span class="si">{</span><span class="n">fd</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="n">select_fds</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">conn</span><span class="p">)</span>
<span class="n">conn</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="n">conn</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">elif</span> <span class="n">fd</span> <span class="ow">in</span> <span class="n">fds</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Reading timer </span><span class="si">{</span><span class="n">fd</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="n">count</span> <span class="o">=</span> <span class="nb">int</span><span class="o">.</span><span class="n">from_bytes</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">fd</span><span class="p">,</span> <span class="mi">8</span><span class="p">),</span> <span class="n">byteorder</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">byteorder</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Timer </span><span class="si">{</span><span class="n">fds</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="n">fd</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="si">}</span><span class="s2"> expired </span><span class="si">{</span><span class="n">count</span><span class="si">}</span><span class="s2"> times&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Unknown file descriptor </span><span class="si">{</span><span class="n">fd</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">finally</span><span class="p">:</span>
<span class="k">for</span> <span class="n">fd</span> <span class="ow">in</span> <span class="n">fds</span><span class="p">:</span>
<span class="n">os</span><span class="o">.</span><span class="n">close</span><span class="p">(</span><span class="n">fd</span><span class="p">)</span>
<span class="n">sock</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="n">sock</span> <span class="o">=</span> <span class="kc">None</span>
</pre></div>
</div>
</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="#">timer file descriptor HOWTO</a><ul>
<li><a class="reference internal" href="#examples">Examples</a></li>
</ul>
</li>
</ul>
</div>
<div>
<h4>Previous topic</h4>
<p class="topless"><a href="isolating-extensions.html"
title="previous chapter">Isolating Extension Modules</a></p>
</div>
<div>
<h4>Next topic</h4>
<p class="topless"><a href="mro.html"
title="next chapter">The Python 2.3 Method Resolution Order</a></p>
</div>
<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 href="https://github.com/python/cpython/blob/main/Doc/howto/timerfd.rst"
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="mro.html" title="The Python 2.3 Method Resolution Order"
>next</a> |</li>
<li class="right" >
<a href="isolating-extensions.html" title="Isolating Extension Modules"
>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.13.3 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="">timer file descriptor HOWTO</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-2025, 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 Apr 08, 2025 (14:33 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>