[code.view]

[top] / python / PyMOTW / docs / signal / index.html


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <title>signal – Receive notification of asynchronous system events &mdash; Python Module of the Week</title>
    <link rel="stylesheet" href="../_static/sphinxdoc.css" type="text/css" />
    <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    '../',
        VERSION:     '1.132',
        COLLAPSE_INDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true
      };
    </script>
    <script type="text/javascript" src="../_static/jquery.js"></script>
    <script type="text/javascript" src="../_static/underscore.js"></script>
    <script type="text/javascript" src="../_static/doctools.js"></script>
    <link rel="author" title="About these documents" href="../about.html" />
    <link rel="top" title="Python Module of the Week" href="../index.html" />
    <link rel="up" title="Interprocess Communication and Networking" href="../ipc.html" />
    <link rel="next" title="subprocess – Work with additional processes" href="../subprocess/index.html" />
    <link rel="prev" title="asyncore – Asynchronous I/O handler" href="../asyncore/index.html" /> 
  </head>
  <body>
    <div class="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="../subprocess/index.html" title="subprocess – Work with additional processes"
             accesskey="N">next</a> |</li>
        <li class="right" >
          <a href="../asyncore/index.html" title="asyncore – Asynchronous I/O handler"
             accesskey="P">previous</a> |</li>
        <li><a href="../contents.html">PyMOTW</a> &raquo;</li>
          <li><a href="../ipc.html" accesskey="U">Interprocess Communication and Networking</a> &raquo;</li> 
      </ul>
    </div>
      <div class="sphinxsidebar">
        <div class="sphinxsidebarwrapper">
  <h3><a href="../contents.html">Table Of Contents</a></h3>
  <ul>
<li><a class="reference internal" href="#">signal &#8211; Receive notification of asynchronous system events</a><ul>
<li><a class="reference internal" href="#receiving-signals">Receiving Signals</a></li>
<li><a class="reference internal" href="#getsignal">getsignal()</a></li>
<li><a class="reference internal" href="#sending-signals">Sending Signals</a></li>
<li><a class="reference internal" href="#alarms">Alarms</a></li>
<li><a class="reference internal" href="#ignoring-signals">Ignoring Signals</a></li>
<li><a class="reference internal" href="#signals-and-threads">Signals and Threads</a></li>
</ul>
</li>
</ul>

  <h4>Previous topic</h4>
  <p class="topless"><a href="../asyncore/index.html"
                        title="previous chapter">asyncore &#8211; Asynchronous I/O handler</a></p>
  <h4>Next topic</h4>
  <p class="topless"><a href="../subprocess/index.html"
                        title="next chapter">subprocess &#8211; Work with additional processes</a></p>
  <h3>This Page</h3>
  <ul class="this-page-menu">
    <li><a href="../_sources/signal/index.txt"
           rel="nofollow">Show Source</a></li>
  </ul>
<div id="searchbox" style="display: none">
  <h3>Quick search</h3>
    <form class="search" action="../search.html" method="get">
      <input type="text" name="q" size="18" />
      <input type="submit" value="Go" />
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>
    <p class="searchtip" style="font-size: 90%">
    Enter search terms or a module, class or function name.
    </p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body">
            
  <div class="section" id="module-signal">
<span id="signal-receive-notification-of-asynchronous-system-events"></span><h1>signal &#8211; Receive notification of asynchronous system events<a class="headerlink" href="#module-signal" title="Permalink to this headline">¶</a></h1>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Purpose:</th><td class="field-body">Receive notification of asynchronous system events</td>
</tr>
<tr class="field"><th class="field-name">Python Version:</th><td class="field-body">1.4 and later</td>
</tr>
</tbody>
</table>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Programming with Unix signal handlers is a non-trivial endeavor. This is an introduction,
and does not include all of the details you may need to use signals successfully on every
platform. There is some degree of standardization across versions of Unix, but there is
also some variation, so consult documentation for your OS if you run into trouble.</p>
</div>
<p>Signals are an operating system feature that provide a means of
notifying your program of an event, and having it handled
asynchronously.  They can be generated by the system itself, or sent
from one process to another.  Since signals interrupt the regular flow
of your program, it is possible that some operations (especially I/O)
may produce error if a signal is received in the middle.</p>
<p>Signals are identified by integers and are defined in the operating
system C headers.  Python exposes the signals appropriate for the
platform as symbols in the <a class="reference internal" href="#module-signal" title="signal: Receive notification of asynchronous system events"><tt class="xref py py-mod docutils literal"><span class="pre">signal</span></tt></a> module.  For the examples
below, I will use <tt class="docutils literal"><span class="pre">SIGINT</span></tt> and <tt class="docutils literal"><span class="pre">SIGUSR1</span></tt>.  Both are typically
defined for all Unix and Unix-like systems.</p>
<div class="section" id="receiving-signals">
<h2>Receiving Signals<a class="headerlink" href="#receiving-signals" title="Permalink to this headline">¶</a></h2>
<p>As with other forms of event-based programming, signals are received
by establishing a callback function, called a <em>signal handler</em>, that
is invoked when the signal occurs.  The arguments to your signal
handler are the signal number and the stack frame from the point in
your program that was interrupted by the signal.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">signal</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">time</span>

<span class="k">def</span> <span class="nf">receive_signal</span><span class="p">(</span><span class="n">signum</span><span class="p">,</span> <span class="n">stack</span><span class="p">):</span>
    <span class="k">print</span> <span class="s">&#39;Received:&#39;</span><span class="p">,</span> <span class="n">signum</span>

<span class="n">signal</span><span class="o">.</span><span class="n">signal</span><span class="p">(</span><span class="n">signal</span><span class="o">.</span><span class="n">SIGUSR1</span><span class="p">,</span> <span class="n">receive_signal</span><span class="p">)</span>
<span class="n">signal</span><span class="o">.</span><span class="n">signal</span><span class="p">(</span><span class="n">signal</span><span class="o">.</span><span class="n">SIGUSR2</span><span class="p">,</span> <span class="n">receive_signal</span><span class="p">)</span>

<span class="k">print</span> <span class="s">&#39;My PID is:&#39;</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">getpid</span><span class="p">()</span>

<span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
    <span class="k">print</span> <span class="s">&#39;Waiting...&#39;</span>
    <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
</pre></div>
</div>
<p>This relatively simple example script loops indefinitely, pausing for
a few seconds each time.  When a signal comes in, the sleep call is
interrupted and the signal handler <tt class="docutils literal"><span class="pre">receive_signal()</span></tt> prints the
signal number.  When the signal handler returns, the loop continues.</p>
<p>To send signals to the running program, I use the command line program
kill.  To produce the output below, I ran <tt class="docutils literal"><span class="pre">signal_signal.py</span></tt> in one
window, then <tt class="docutils literal"><span class="pre">kill</span> <span class="pre">-USR1</span> <span class="pre">$pid</span></tt>, <tt class="docutils literal"><span class="pre">kill</span> <span class="pre">-USR2</span> <span class="pre">$pid</span></tt>, and <tt class="docutils literal"><span class="pre">kill</span> <span class="pre">-INT</span>
<span class="pre">$pid</span></tt> in another.</p>
<div class="highlight-python"><pre>$ python signal_signal.py
My PID is: 71387
Waiting...
Waiting...
Waiting...
Received: 30
Waiting...
Waiting...
Received: 31
Waiting...
Waiting...
Traceback (most recent call last):
  File "signal_signal.py", line 25, in &lt;module&gt;
    time.sleep(3)
KeyboardInterrupt</pre>
</div>
</div>
<div class="section" id="getsignal">
<h2>getsignal()<a class="headerlink" href="#getsignal" title="Permalink to this headline">¶</a></h2>
<p>To see what signal handlers are registered for a signal, use
<tt class="xref py py-func docutils literal"><span class="pre">getsignal()</span></tt>.  Pass the signal number as argument.  The return
value is the registered handler, or one of the special values
<tt class="docutils literal"><span class="pre">signal.SIG_IGN</span></tt> (if the signal is being ignored),
<tt class="docutils literal"><span class="pre">signal.SIG_DFL</span></tt> (if the default behavior is being used), or
<tt class="xref docutils literal"><span class="pre">None</span></tt> (if the existing signal handler was registered from C, rather
than Python).</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">signal</span>

<span class="k">def</span> <span class="nf">alarm_received</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">stack</span><span class="p">):</span>
    <span class="k">return</span>

<span class="n">signal</span><span class="o">.</span><span class="n">signal</span><span class="p">(</span><span class="n">signal</span><span class="o">.</span><span class="n">SIGALRM</span><span class="p">,</span> <span class="n">alarm_received</span><span class="p">)</span>

<span class="n">signals_to_names</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="nb">dir</span><span class="p">(</span><span class="n">signal</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">n</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s">&#39;SIG&#39;</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">n</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s">&#39;SIG_&#39;</span><span class="p">):</span>
        <span class="n">signals_to_names</span><span class="p">[</span><span class="nb">getattr</span><span class="p">(</span><span class="n">signal</span><span class="p">,</span> <span class="n">n</span><span class="p">)]</span> <span class="o">=</span> <span class="n">n</span>

<span class="k">for</span> <span class="n">s</span><span class="p">,</span> <span class="n">name</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">signals_to_names</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span>
    <span class="n">handler</span> <span class="o">=</span> <span class="n">signal</span><span class="o">.</span><span class="n">getsignal</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">handler</span> <span class="ow">is</span> <span class="n">signal</span><span class="o">.</span><span class="n">SIG_DFL</span><span class="p">:</span>
        <span class="n">handler</span> <span class="o">=</span> <span class="s">&#39;SIG_DFL&#39;</span>
    <span class="k">elif</span> <span class="n">handler</span> <span class="ow">is</span> <span class="n">signal</span><span class="o">.</span><span class="n">SIG_IGN</span><span class="p">:</span>
        <span class="n">handler</span> <span class="o">=</span> <span class="s">&#39;SIG_IGN&#39;</span>
    <span class="k">print</span> <span class="s">&#39;</span><span class="si">%-10s</span><span class="s"> (</span><span class="si">%2d</span><span class="s">):&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">s</span><span class="p">),</span> <span class="n">handler</span>
</pre></div>
</div>
<p>Again, since each OS may have different signals defined, the output
you see from running this on other systems may vary.  This is from OS
X:</p>
<div class="highlight-python"><pre>$ python signal_getsignal.py
SIGHUP     ( 1): SIG_DFL
SIGINT     ( 2): &amp;lt;built-in function default_int_handler&amp;gt;
SIGQUIT    ( 3): SIG_DFL
SIGILL     ( 4): SIG_DFL
SIGTRAP    ( 5): SIG_DFL
SIGIOT     ( 6): SIG_DFL
SIGEMT     ( 7): SIG_DFL
SIGFPE     ( 8): SIG_DFL
SIGKILL    ( 9): None
SIGBUS     (10): SIG_DFL
SIGSEGV    (11): SIG_DFL
SIGSYS     (12): SIG_DFL
SIGPIPE    (13): SIG_IGN
SIGALRM    (14): &amp;lt;function alarm_received at 0x7c3f0&amp;gt;
SIGTERM    (15): SIG_DFL
SIGURG     (16): SIG_DFL
SIGSTOP    (17): None
SIGTSTP    (18): SIG_DFL
SIGCONT    (19): SIG_DFL
SIGCHLD    (20): SIG_DFL
SIGTTIN    (21): SIG_DFL
SIGTTOU    (22): SIG_DFL
SIGIO      (23): SIG_DFL
SIGXCPU    (24): SIG_DFL
SIGXFSZ    (25): SIG_IGN
SIGVTALRM  (26): SIG_DFL
SIGPROF    (27): SIG_DFL
SIGWINCH   (28): SIG_DFL
SIGINFO    (29): SIG_DFL
SIGUSR1    (30): SIG_DFL
SIGUSR2    (31): SIG_DFL</pre>
</div>
</div>
<div class="section" id="sending-signals">
<h2>Sending Signals<a class="headerlink" href="#sending-signals" title="Permalink to this headline">¶</a></h2>
<p>The function for sending signals is <tt class="docutils literal"><span class="pre">os.kill()</span></tt>.  Its use is covered
in the section on the <a class="reference internal" href="../os/index.html#module-os" title="os: Portable access to operating system specific features."><tt class="xref py py-mod docutils literal"><span class="pre">os</span></tt></a> module,
<a class="reference internal" href="../os/index.html#creating-processes-with-os-fork"><em>Creating Processes with os.fork()</em></a>.</p>
</div>
<div class="section" id="alarms">
<h2>Alarms<a class="headerlink" href="#alarms" title="Permalink to this headline">¶</a></h2>
<p>Alarms are a special sort of signal, where your program asks the OS to
notify it after some period of time has elapsed.  As <a class="reference external" href="http://docs.python.org/lib/node545.html">the standard
module documentation for os</a> points out, this is useful
for avoiding blocking indefinitely on an I/O operation or other system
call.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">signal</span>
<span class="kn">import</span> <span class="nn">time</span>

<span class="k">def</span> <span class="nf">receive_alarm</span><span class="p">(</span><span class="n">signum</span><span class="p">,</span> <span class="n">stack</span><span class="p">):</span>
    <span class="k">print</span> <span class="s">&#39;Alarm :&#39;</span><span class="p">,</span> <span class="n">time</span><span class="o">.</span><span class="n">ctime</span><span class="p">()</span>

<span class="c"># Call receive_alarm in 2 seconds</span>
<span class="n">signal</span><span class="o">.</span><span class="n">signal</span><span class="p">(</span><span class="n">signal</span><span class="o">.</span><span class="n">SIGALRM</span><span class="p">,</span> <span class="n">receive_alarm</span><span class="p">)</span>
<span class="n">signal</span><span class="o">.</span><span class="n">alarm</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>

<span class="k">print</span> <span class="s">&#39;Before:&#39;</span><span class="p">,</span> <span class="n">time</span><span class="o">.</span><span class="n">ctime</span><span class="p">()</span>
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
<span class="k">print</span> <span class="s">&#39;After :&#39;</span><span class="p">,</span> <span class="n">time</span><span class="o">.</span><span class="n">ctime</span><span class="p">()</span>
</pre></div>
</div>
<p>In this example, the call to <tt class="xref py py-func docutils literal"><span class="pre">sleep()</span></tt> does not last the full 4
seconds.</p>
<div class="highlight-python"><pre>$ python signal_alarm.py
Before: Sun Aug 17 10:51:09 2008
Alarm : Sun Aug 17 10:51:11 2008
After : Sun Aug 17 10:51:11 2008</pre>
</div>
</div>
<div class="section" id="ignoring-signals">
<h2>Ignoring Signals<a class="headerlink" href="#ignoring-signals" title="Permalink to this headline">¶</a></h2>
<p>To ignore a signal, register <tt class="docutils literal"><span class="pre">SIG_IGN</span></tt> as the handler.  This script
replaces the default handler for <tt class="docutils literal"><span class="pre">SIGINT</span></tt> with <tt class="docutils literal"><span class="pre">SIG_IGN</span></tt>, and
registers a handler for <tt class="docutils literal"><span class="pre">SIGUSR1</span></tt>.  Then it uses
<tt class="xref py py-func docutils literal"><span class="pre">signal.pause()</span></tt> to wait for a signal to be received.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">signal</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">time</span>

<span class="k">def</span> <span class="nf">do_exit</span><span class="p">(</span><span class="n">sig</span><span class="p">,</span> <span class="n">stack</span><span class="p">):</span>
    <span class="k">raise</span> <span class="ne">SystemExit</span><span class="p">(</span><span class="s">&#39;Exiting&#39;</span><span class="p">)</span>

<span class="n">signal</span><span class="o">.</span><span class="n">signal</span><span class="p">(</span><span class="n">signal</span><span class="o">.</span><span class="n">SIGINT</span><span class="p">,</span> <span class="n">signal</span><span class="o">.</span><span class="n">SIG_IGN</span><span class="p">)</span>
<span class="n">signal</span><span class="o">.</span><span class="n">signal</span><span class="p">(</span><span class="n">signal</span><span class="o">.</span><span class="n">SIGUSR1</span><span class="p">,</span> <span class="n">do_exit</span><span class="p">)</span>

<span class="k">print</span> <span class="s">&#39;My PID:&#39;</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">getpid</span><span class="p">()</span>

<span class="n">signal</span><span class="o">.</span><span class="n">pause</span><span class="p">()</span>
</pre></div>
</div>
<p>Normally <tt class="docutils literal"><span class="pre">SIGINT</span></tt> (the signal sent by the shell to your program when
you hit Ctrl-C) raises a <a class="reference internal" href="../exceptions/index.html#exceptions-keyboardinterrupt"><em>KeyboardInterrupt</em></a>.  In this example, we ignore <tt class="docutils literal"><span class="pre">SIGINT</span></tt>
and raise <a class="reference internal" href="../exceptions/index.html#exceptions-systemexit"><em>SystemExit</em></a> when we see
<tt class="docutils literal"><span class="pre">SIGUSR1</span></tt>.  Each <tt class="docutils literal"><span class="pre">^C</span></tt> represents an attempt to use Ctrl-C to kill
the script from the terminal.  Using <tt class="docutils literal"><span class="pre">kill</span> <span class="pre">-USR1</span> <span class="pre">72598</span></tt> from another
terminal eventually causes the script to exit.</p>
<div class="highlight-python"><pre>$ python signal_ignore.py
My PID: 72598
^C^C^C^CExiting</pre>
</div>
</div>
<div class="section" id="signals-and-threads">
<h2>Signals and Threads<a class="headerlink" href="#signals-and-threads" title="Permalink to this headline">¶</a></h2>
<p>Signals and threads don&#8217;t generally mix well because only the main
thread of a process will receive signals.  The following example sets
up a signal handler, waits for the signal in one thread, and sends the
signal from another.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">signal</span>
<span class="kn">import</span> <span class="nn">threading</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">time</span>

<span class="k">def</span> <span class="nf">signal_handler</span><span class="p">(</span><span class="n">num</span><span class="p">,</span> <span class="n">stack</span><span class="p">):</span>
    <span class="k">print</span> <span class="s">&#39;Received signal </span><span class="si">%d</span><span class="s"> in </span><span class="si">%s</span><span class="s">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">num</span><span class="p">,</span> <span class="n">threading</span><span class="o">.</span><span class="n">currentThread</span><span class="p">())</span>

<span class="n">signal</span><span class="o">.</span><span class="n">signal</span><span class="p">(</span><span class="n">signal</span><span class="o">.</span><span class="n">SIGUSR1</span><span class="p">,</span> <span class="n">signal_handler</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">wait_for_signal</span><span class="p">():</span>
    <span class="k">print</span> <span class="s">&#39;Waiting for signal in&#39;</span><span class="p">,</span> <span class="n">threading</span><span class="o">.</span><span class="n">currentThread</span><span class="p">()</span>
    <span class="n">signal</span><span class="o">.</span><span class="n">pause</span><span class="p">()</span>
    <span class="k">print</span> <span class="s">&#39;Done waiting&#39;</span>

<span class="c"># Start a thread that will not receive the signal</span>
<span class="n">receiver</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="n">wait_for_signal</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s">&#39;receiver&#39;</span><span class="p">)</span>
<span class="n">receiver</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">0.1</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">send_signal</span><span class="p">():</span>
    <span class="k">print</span> <span class="s">&#39;Sending signal in&#39;</span><span class="p">,</span> <span class="n">threading</span><span class="o">.</span><span class="n">currentThread</span><span class="p">()</span>
    <span class="n">os</span><span class="o">.</span><span class="n">kill</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">getpid</span><span class="p">(),</span> <span class="n">signal</span><span class="o">.</span><span class="n">SIGUSR1</span><span class="p">)</span>

<span class="n">sender</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="n">send_signal</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s">&#39;sender&#39;</span><span class="p">)</span>
<span class="n">sender</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
<span class="n">sender</span><span class="o">.</span><span class="n">join</span><span class="p">()</span>

<span class="c"># Wait for the thread to see the signal (not going to happen!)</span>
<span class="k">print</span> <span class="s">&#39;Waiting for&#39;</span><span class="p">,</span> <span class="n">receiver</span>
<span class="n">signal</span><span class="o">.</span><span class="n">alarm</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="n">receiver</span><span class="o">.</span><span class="n">join</span><span class="p">()</span>
</pre></div>
</div>
<p>Notice that the signal handlers were all registered in the main
thread.  This is a requirement of the signal module implementation for
Python, regardless of underlying platform support for mixing threads
and signals.  Although the receiver thread calls
<tt class="xref py py-func docutils literal"><span class="pre">signal.pause()</span></tt>, it does not receive the signal.  The
<tt class="docutils literal"><span class="pre">signal.alarm(2)</span></tt> call near the end of the example prevents an
infinite block, since the receiver thread will never exit.</p>
<div class="highlight-python"><pre>$ python signal_threads.py
Waiting for signal in &lt;Thread(receiver, started)&gt;
Sending signal in &lt;Thread(sender, started)&gt;
Received signal 30 in &lt;_MainThread(MainThread, started)&gt;
Waiting for &lt;Thread(receiver, started)&gt;
Alarm clock</pre>
</div>
<p>Although alarms can be set in threads, they are also received by the
main thread.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">signal</span>
<span class="kn">import</span> <span class="nn">time</span>
<span class="kn">import</span> <span class="nn">threading</span>

<span class="k">def</span> <span class="nf">signal_handler</span><span class="p">(</span><span class="n">num</span><span class="p">,</span> <span class="n">stack</span><span class="p">):</span>
    <span class="k">print</span> <span class="n">time</span><span class="o">.</span><span class="n">ctime</span><span class="p">(),</span> <span class="s">&#39;Alarm in&#39;</span><span class="p">,</span> <span class="n">threading</span><span class="o">.</span><span class="n">currentThread</span><span class="p">()</span>

<span class="n">signal</span><span class="o">.</span><span class="n">signal</span><span class="p">(</span><span class="n">signal</span><span class="o">.</span><span class="n">SIGALRM</span><span class="p">,</span> <span class="n">signal_handler</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">use_alarm</span><span class="p">():</span>
    <span class="k">print</span> <span class="n">time</span><span class="o">.</span><span class="n">ctime</span><span class="p">(),</span> <span class="s">&#39;Setting alarm in&#39;</span><span class="p">,</span> <span class="n">threading</span><span class="o">.</span><span class="n">currentThread</span><span class="p">()</span>
    <span class="n">signal</span><span class="o">.</span><span class="n">alarm</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
    <span class="k">print</span> <span class="n">time</span><span class="o">.</span><span class="n">ctime</span><span class="p">(),</span> <span class="s">&#39;Sleeping in&#39;</span><span class="p">,</span> <span class="n">threading</span><span class="o">.</span><span class="n">currentThread</span><span class="p">()</span>
    <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
    <span class="k">print</span> <span class="n">time</span><span class="o">.</span><span class="n">ctime</span><span class="p">(),</span> <span class="s">&#39;Done with sleep&#39;</span>

<span class="c"># Start a thread that will not receive the signal</span>
<span class="n">alarm_thread</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="n">use_alarm</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s">&#39;alarm_thread&#39;</span><span class="p">)</span>
<span class="n">alarm_thread</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">0.1</span><span class="p">)</span>

<span class="c"># Wait for the thread to see the signal (not going to happen!)</span>
<span class="k">print</span> <span class="n">time</span><span class="o">.</span><span class="n">ctime</span><span class="p">(),</span> <span class="s">&#39;Waiting for&#39;</span><span class="p">,</span> <span class="n">alarm_thread</span>
<span class="n">alarm_thread</span><span class="o">.</span><span class="n">join</span><span class="p">()</span>

<span class="k">print</span> <span class="n">time</span><span class="o">.</span><span class="n">ctime</span><span class="p">(),</span> <span class="s">&#39;Exiting normally&#39;</span>
</pre></div>
</div>
<p>Notice that the alarm does not abort the <tt class="xref py py-func docutils literal"><span class="pre">sleep()</span></tt> call in
<tt class="xref py py-func docutils literal"><span class="pre">use_alarm()</span></tt>.</p>
<div class="highlight-python"><pre>$ python signal_threads_alarm.py
Sun Aug 17 12:06:00 2008 Setting alarm in &lt;Thread(alarm_thread, started)&gt;
Sun Aug 17 12:06:00 2008 Sleeping in &lt;Thread(alarm_thread, started)&gt;
Sun Aug 17 12:06:00 2008 Waiting for &lt;Thread(alarm_thread, started)&gt;;
Sun Aug 17 12:06:03 2008 Done with sleep
Sun Aug 17 12:06:03 2008 Alarm in &lt;_MainThread(MainThread, started)&gt;
Sun Aug 17 12:06:03 2008 Exiting normally</pre>
</div>
<div class="admonition-see-also admonition seealso">
<p class="first admonition-title">See also</p>
<dl class="last docutils">
<dt><a class="reference external" href="http://docs.python.org/lib/module-signal.html">signal</a></dt>
<dd>Standard library documentation for this module.</dd>
<dt><a class="reference internal" href="../os/index.html#creating-processes-with-os-fork"><em>Creating Processes with os.fork()</em></a></dt>
<dd>The <tt class="xref py py-func docutils literal"><span class="pre">kill()</span></tt> function can be used to send signals
between processes.</dd>
</dl>
</div>
</div>
</div>


          </div>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="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="../subprocess/index.html" title="subprocess – Work with additional processes"
             >next</a> |</li>
        <li class="right" >
          <a href="../asyncore/index.html" title="asyncore – Asynchronous I/O handler"
             >previous</a> |</li>
        <li><a href="../contents.html">PyMOTW</a> &raquo;</li>
          <li><a href="../ipc.html" >Interprocess Communication and Networking</a> &raquo;</li> 
      </ul>
    </div>
    <div class="footer">
      &copy; Copyright Doug Hellmann.
      Last updated on Oct 24, 2010.
      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a>.

    <br/><a href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/" rel="license"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/3.0/us/88x31.png"/></a>
    
    </div>
  </body>
</html>

[top] / python / PyMOTW / docs / signal / index.html

contact | logmethods.com