UNPKG

boost-react-native-bundle

Version:

Boost library as in https://sourceforge.net/projects/boost/files/boost/1.57.0/

470 lines (461 loc) 265 kB
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> <title>Thread Management</title> <link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css"> <meta name="generator" content="DocBook XSL Stylesheets V1.78.1"> <link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset"> <link rel="up" href="../thread.html" title="Chapter&#160;30.&#160;Thread 4.4.0"> <link rel="prev" href="future.html" title="Future"> <link rel="next" href="ScopedThreads.html" title="Scoped Threads"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> <table cellpadding="2" width="100%"><tr> <td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td> <td align="center"><a href="../../../index.html">Home</a></td> <td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td> <td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> <td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> <td align="center"><a href="../../../more/index.htm">More</a></td> </tr></table> <hr> <div class="spirit-nav"> <a accesskey="p" href="future.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../thread.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="ScopedThreads.html"><img src="../../../doc/src/images/next.png" alt="Next"></a> </div> <div class="section"> <div class="titlepage"><div><div><h2 class="title" style="clear: both"> <a name="thread.thread_management"></a><a class="link" href="thread_management.html" title="Thread Management">Thread Management</a> </h2></div></div></div> <div class="toc"><dl class="toc"> <dt><span class="section"><a href="thread_management.html#thread.thread_management.synopsis">Synopsis</a></span></dt> <dt><span class="section"><a href="thread_management.html#thread.thread_management.tutorial">Tutorial</a></span></dt> <dt><span class="section"><a href="thread_management.html#thread.thread_management.thread">Class <code class="computeroutput"><span class="identifier">thread</span></code></a></span></dt> <dt><span class="section"><a href="thread_management.html#thread.thread_management.this_thread">Namespace <code class="computeroutput"><span class="identifier">this_thread</span></code></a></span></dt> <dt><span class="section"><a href="thread_management.html#thread.thread_management.threadgroup">Class <code class="computeroutput"><span class="identifier">thread_group</span></code> EXTENSION</a></span></dt> </dl></div> <div class="section"> <div class="titlepage"><div><div><h3 class="title"> <a name="thread.thread_management.synopsis"></a><a class="link" href="thread_management.html#thread.thread_management.synopsis" title="Synopsis">Synopsis</a> </h3></div></div></div> <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">thread</span><span class="special">/</span><span class="identifier">thread</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span> <span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> <span class="keyword">class</span> <span class="identifier">thread</span><span class="special">;</span> <span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span><span class="identifier">thread</span><span class="special">&amp;</span> <span class="identifier">lhs</span><span class="special">,</span><span class="identifier">thread</span><span class="special">&amp;</span> <span class="identifier">rhs</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span> <span class="keyword">namespace</span> <span class="identifier">this_thread</span> <span class="special">{</span> <span class="identifier">thread</span><span class="special">::</span><span class="identifier">id</span> <span class="identifier">get_id</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span> <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">TimeDuration</span><span class="special">&gt;</span> <span class="keyword">void</span> <span class="identifier">yield</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span> <span class="comment">// DEPRECATED</span> <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Duration</span><span class="special">&gt;</span> <span class="keyword">void</span> <span class="identifier">sleep_until</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">chrono</span><span class="special">::</span><span class="identifier">time_point</span><span class="special">&lt;</span><span class="identifier">Clock</span><span class="special">,</span> <span class="identifier">Duration</span><span class="special">&gt;&amp;</span> <span class="identifier">abs_time</span><span class="special">);</span> <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Period</span><span class="special">&gt;</span> <span class="keyword">void</span> <span class="identifier">sleep_for</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">chrono</span><span class="special">::</span><span class="identifier">duration</span><span class="special">&lt;</span><span class="identifier">Rep</span><span class="special">,</span> <span class="identifier">Period</span><span class="special">&gt;&amp;</span> <span class="identifier">rel_time</span><span class="special">);</span> <span class="keyword">namespace</span> <span class="identifier">no_interruption_point</span> <span class="comment">// EXTENSION</span> <span class="special">{</span> <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Duration</span><span class="special">&gt;</span> <span class="keyword">void</span> <span class="identifier">sleep_until</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">chrono</span><span class="special">::</span><span class="identifier">time_point</span><span class="special">&lt;</span><span class="identifier">Clock</span><span class="special">,</span> <span class="identifier">Duration</span><span class="special">&gt;&amp;</span> <span class="identifier">abs_time</span><span class="special">);</span> <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Period</span><span class="special">&gt;</span> <span class="keyword">void</span> <span class="identifier">sleep_for</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">chrono</span><span class="special">::</span><span class="identifier">duration</span><span class="special">&lt;</span><span class="identifier">Rep</span><span class="special">,</span> <span class="identifier">Period</span><span class="special">&gt;&amp;</span> <span class="identifier">rel_time</span><span class="special">);</span> <span class="special">}</span> <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Callable</span><span class="special">&gt;</span> <span class="keyword">void</span> <span class="identifier">at_thread_exit</span><span class="special">(</span><span class="identifier">Callable</span> <span class="identifier">func</span><span class="special">);</span> <span class="comment">// EXTENSION</span> <span class="keyword">void</span> <span class="identifier">interruption_point</span><span class="special">();</span> <span class="comment">// EXTENSION</span> <span class="keyword">bool</span> <span class="identifier">interruption_requested</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span> <span class="comment">// EXTENSION</span> <span class="keyword">bool</span> <span class="identifier">interruption_enabled</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span> <span class="comment">// EXTENSION </span> <span class="keyword">class</span> <span class="identifier">disable_interruption</span><span class="special">;</span> <span class="comment">// EXTENSION</span> <span class="keyword">class</span> <span class="identifier">restore_interruption</span><span class="special">;</span> <span class="comment">// EXTENSION</span> <span class="preprocessor">#if</span> <span class="identifier">defined</span> <span class="identifier">BOOST_THREAD_USES_DATETIME</span> <span class="keyword">template</span> <span class="special">&lt;</span><span class="identifier">TimeDuration</span><span class="special">&gt;</span> <span class="keyword">void</span> <span class="identifier">sleep</span><span class="special">(</span><span class="identifier">TimeDuration</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">rel_time</span><span class="special">);</span> <span class="comment">// DEPRECATED</span> <span class="keyword">void</span> <span class="identifier">sleep</span><span class="special">(</span><span class="identifier">system_time</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">abs_time</span><span class="special">);</span> <span class="comment">// DEPRECATED</span> <span class="preprocessor">#endif</span> <span class="special">}</span> <span class="keyword">class</span> <span class="identifier">thread_group</span><span class="special">;</span> <span class="comment">// EXTENSION</span> <span class="special">}</span> </pre> </div> <div class="section"> <div class="titlepage"><div><div><h3 class="title"> <a name="thread.thread_management.tutorial"></a><a class="link" href="thread_management.html#thread.thread_management.tutorial" title="Tutorial">Tutorial</a> </h3></div></div></div> <div class="toc"><dl class="toc"> <dt><span class="section"><a href="thread_management.html#thread.thread_management.tutorial.launching">Launching threads</a></span></dt> <dt><span class="section"><a href="thread_management.html#thread.thread_management.tutorial.attributes">Thread attributes</a></span></dt> <dt><span class="section"><a href="thread_management.html#thread.thread_management.tutorial.exceptions">Exceptions in thread functions</a></span></dt> <dt><span class="section"><a href="thread_management.html#thread.thread_management.tutorial.detach">Detaching thread</a></span></dt> <dt><span class="section"><a href="thread_management.html#thread.thread_management.tutorial.join">Joining a thread</a></span></dt> <dt><span class="section"><a href="thread_management.html#thread.thread_management.tutorial.destructor1">Destructor V1</a></span></dt> <dt><span class="section"><a href="thread_management.html#thread.thread_management.tutorial.destructor2">Destructor V2</a></span></dt> <dt><span class="section"><a href="thread_management.html#thread.thread_management.tutorial.interruption">Interruption</a></span></dt> <dt><span class="section"><a href="thread_management.html#thread.thread_management.tutorial.id">Thread IDs</a></span></dt> <dt><span class="section"><a href="thread_management.html#thread.thread_management.tutorial.native_in">Using native interfaces with Boost.Thread resources</a></span></dt> <dt><span class="section"><a href="thread_management.html#thread.thread_management.tutorial.native_from">Using Boost.Thread interfaces in a native thread</a></span></dt> </dl></div> <p> The <a class="link" href="thread_management.html#thread.thread_management.thread" title="Class thread"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span></code></a> class is responsible for launching and managing threads. Each <a class="link" href="thread_management.html#thread.thread_management.thread" title="Class thread"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span></code></a> object represents a single thread of execution, or <span class="emphasis"><em>Not-a-Thread</em></span>, and at most one <a class="link" href="thread_management.html#thread.thread_management.thread" title="Class thread"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span></code></a> object represents a given thread of execution: objects of type <a class="link" href="thread_management.html#thread.thread_management.thread" title="Class thread"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span></code></a> are not copyable. </p> <p> Objects of type <a class="link" href="thread_management.html#thread.thread_management.thread" title="Class thread"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span></code></a> are movable, however, so they can be stored in move-aware containers, and returned from functions. This allows the details of thread creation to be wrapped in a function. </p> <pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span> <span class="identifier">make_thread</span><span class="special">();</span> <span class="keyword">void</span> <span class="identifier">f</span><span class="special">()</span> <span class="special">{</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span> <span class="identifier">some_thread</span><span class="special">=</span><span class="identifier">make_thread</span><span class="special">();</span> <span class="identifier">some_thread</span><span class="special">.</span><span class="identifier">join</span><span class="special">();</span> <span class="special">}</span> </pre> <div class="note"><table border="0" summary="Note"> <tr> <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td> <th align="left">Note</th> </tr> <tr><td align="left" valign="top"> <p> On compilers that support rvalue references, <a class="link" href="thread_management.html#thread.thread_management.thread" title="Class thread"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span></code></a> provides a proper move constructor and move-assignment operator, and therefore meets the C++0x <span class="emphasis"><em>MoveConstructible</em></span> and <span class="emphasis"><em>MoveAssignable</em></span> concepts. With such compilers, <a class="link" href="thread_management.html#thread.thread_management.thread" title="Class thread"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span></code></a> can therefore be used with containers that support those concepts. </p> <p> For other compilers, move support is provided with a move emulation layer, so containers must explicitly detect that move emulation layer. See &lt;boost/thread/detail/move.hpp&gt; for details. </p> </td></tr> </table></div> <div class="section"> <div class="titlepage"><div><div><h4 class="title"> <a name="thread.thread_management.tutorial.launching"></a><a class="link" href="thread_management.html#thread.thread_management.tutorial.launching" title="Launching threads">Launching threads</a> </h4></div></div></div> <p> A new thread is launched by passing an object of a callable type that can be invoked with no parameters to the constructor. The object is then copied into internal storage, and invoked on the newly-created thread of execution. If the object must not (or cannot) be copied, then <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">ref</span></code> can be used to pass in a reference to the function object. In this case, the user of <span class="bold"><strong>Boost.Thread</strong></span> must ensure that the referred-to object outlives the newly-created thread of execution. </p> <pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">callable</span> <span class="special">{</span> <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()();</span> <span class="special">};</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span> <span class="identifier">copies_are_safe</span><span class="special">()</span> <span class="special">{</span> <span class="identifier">callable</span> <span class="identifier">x</span><span class="special">;</span> <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span> <span class="special">}</span> <span class="comment">// x is destroyed, but the newly-created thread has a copy, so this is OK</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span> <span class="identifier">oops</span><span class="special">()</span> <span class="special">{</span> <span class="identifier">callable</span> <span class="identifier">x</span><span class="special">;</span> <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">ref</span><span class="special">(</span><span class="identifier">x</span><span class="special">));</span> <span class="special">}</span> <span class="comment">// x is destroyed, but the newly-created thread still has a reference</span> <span class="comment">// this leads to undefined behaviour</span> </pre> <p> If you wish to construct an instance of <a class="link" href="thread_management.html#thread.thread_management.thread" title="Class thread"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span></code></a> with a function or callable object that requires arguments to be supplied, this can be done by passing additional arguments to the <a class="link" href="thread_management.html#thread.thread_management.thread" title="Class thread"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span></code></a> constructor: </p> <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">find_the_question</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">the_answer</span><span class="special">);</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span> <span class="identifier">deep_thought_2</span><span class="special">(</span><span class="identifier">find_the_question</span><span class="special">,</span><span class="number">42</span><span class="special">);</span> </pre> <p> The arguments are <span class="emphasis"><em>copied</em></span> into the internal thread structure: if a reference is required, use <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">ref</span></code>, just as for references to callable functions. </p> <p> There is an unspecified limit on the number of additional arguments that can be passed. </p> </div> <div class="section"> <div class="titlepage"><div><div><h4 class="title"> <a name="thread.thread_management.tutorial.attributes"></a><a class="link" href="thread_management.html#thread.thread_management.tutorial.attributes" title="Thread attributes">Thread attributes</a> </h4></div></div></div> <p> Thread launched in this way are created with implementation defined thread attributes as stack size, scheduling, priority, ... or any platform specific attributes. It is not evident how to provide a portable interface that allows the user to set the platform specific attributes. Boost.Thread stay in the middle road through the class thread::attributes which allows to set at least in a portable way the stack size as follows: </p> <pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span><span class="special">::</span><span class="identifier">attributes</span> <span class="identifier">attrs</span><span class="special">;</span> <span class="identifier">attrs</span><span class="special">.</span><span class="identifier">set_size</span><span class="special">(</span><span class="number">4096</span><span class="special">*</span><span class="number">10</span><span class="special">);</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span> <span class="identifier">deep_thought_2</span><span class="special">(</span><span class="identifier">attrs</span><span class="special">,</span> <span class="identifier">find_the_question</span><span class="special">,</span> <span class="number">42</span><span class="special">);</span> </pre> <p> Even for this simple attribute there could be portable issues as some platforms could require that the stack size should have a minimal size and/or be a multiple of a given page size. The library adapts the requested size to the platform constraints so that the user doesn't need to take care of it. </p> <p> This is the single attribute that is provided in a portable way. In order to set any other thread attribute at construction time the user needs to use non portable code. </p> <p> On PThread platforms the user will need to get the thread attributes handle and use it for whatever attribute. </p> <p> Next follows how the user could set the stack size and the scheduling policy on PThread platforms. </p> <pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span><span class="special">::</span><span class="identifier">attributes</span> <span class="identifier">attrs</span><span class="special">;</span> <span class="comment">// set portable attributes</span> <span class="comment">// ...</span> <span class="identifier">attr</span><span class="special">.</span><span class="identifier">set_stack_size</span><span class="special">(</span><span class="number">4096</span><span class="special">*</span><span class="number">10</span><span class="special">);</span> <span class="preprocessor">#if</span> <span class="identifier">defined</span><span class="special">(</span><span class="identifier">BOOST_THREAD_PLATFORM_WIN32</span><span class="special">)</span> <span class="comment">// ... window version</span> <span class="preprocessor">#elif</span> <span class="identifier">defined</span><span class="special">(</span><span class="identifier">BOOST_THREAD_PLATFORM_PTHREAD</span><span class="special">)</span> <span class="comment">// ... pthread version</span> <span class="identifier">pthread_attr_setschedpolicy</span><span class="special">(</span><span class="identifier">attr</span><span class="special">.</span><span class="identifier">get_native_handle</span><span class="special">(),</span> <span class="identifier">SCHED_RR</span><span class="special">);</span> <span class="preprocessor">#else</span> <span class="preprocessor">#error</span> <span class="string">"Boost threads unavailable on this platform"</span> <span class="preprocessor">#endif</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span> <span class="identifier">th</span><span class="special">(</span><span class="identifier">attrs</span><span class="special">,</span> <span class="identifier">find_the_question</span><span class="special">,</span> <span class="number">42</span><span class="special">);</span> </pre> <p> On Windows platforms it is not so simple as there is no type that compiles the thread attributes. There is a linked to the creation of a thread on Windows that is emulated via the thread::attributes class. This is the LPSECURITY_ATTRIBUTES lpThreadAttributes. Boost.Thread provides a non portable set_security function so that the user can provide it before the thread creation as follows </p> <pre class="programlisting"><span class="preprocessor">#if</span> <span class="identifier">defined</span><span class="special">(</span><span class="identifier">BOOST_THREAD_PLATFORM_WIN32</span><span class="special">)</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span><span class="special">::</span><span class="identifier">attributes</span> <span class="identifier">attrs</span><span class="special">;</span> <span class="comment">// set portable attributes</span> <span class="identifier">attr</span><span class="special">.</span><span class="identifier">set_stack_size</span><span class="special">(</span><span class="number">4096</span><span class="special">*</span><span class="number">10</span><span class="special">);</span> <span class="comment">// set non portable attribute</span> <span class="identifier">LPSECURITY_ATTRIBUTES</span> <span class="identifier">sec</span><span class="special">;</span> <span class="comment">// init sec </span> <span class="identifier">attr</span><span class="special">.</span><span class="identifier">set_security</span><span class="special">(</span><span class="identifier">sec</span><span class="special">);</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span> <span class="identifier">th</span><span class="special">(</span><span class="identifier">attrs</span><span class="special">,</span> <span class="identifier">find_the_question</span><span class="special">,</span> <span class="number">42</span><span class="special">);</span> <span class="comment">// Set other thread attributes using the native_handle_type.</span> <span class="comment">//...</span> <span class="preprocessor">#else</span> <span class="preprocessor">#error</span> <span class="string">"Platform not supported"</span> <span class="preprocessor">#endif</span> </pre> </div> <div class="section"> <div class="titlepage"><div><div><h4 class="title"> <a name="thread.thread_management.tutorial.exceptions"></a><a class="link" href="thread_management.html#thread.thread_management.tutorial.exceptions" title="Exceptions in thread functions">Exceptions in thread functions</a> </h4></div></div></div> <p> If the function or callable object passed to the <a class="link" href="thread_management.html#thread.thread_management.thread" title="Class thread"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span></code></a> constructor propagates an exception when invoked that is not of type <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread_interrupted</span></code>, <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">terminate</span><span class="special">()</span></code> is called. </p> </div> <div class="section"> <div class="titlepage"><div><div><h4 class="title"> <a name="thread.thread_management.tutorial.detach"></a><a class="link" href="thread_management.html#thread.thread_management.tutorial.detach" title="Detaching thread">Detaching thread</a> </h4></div></div></div> <p> A thread can be detached by explicitly invoking the <a class="link" href="thread_management.html#thread.thread_management.thread.detach" title="Member function detach()"><code class="computeroutput"><span class="identifier">detach</span><span class="special">()</span></code></a> member function on the <a class="link" href="thread_management.html#thread.thread_management.thread" title="Class thread"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span></code></a> object. In this case, the <a class="link" href="thread_management.html#thread.thread_management.thread" title="Class thread"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span></code></a> object ceases to represent the now-detached thread, and instead represents <span class="emphasis"><em>Not-a-Thread</em></span>. </p> <pre class="programlisting"><span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span> <span class="identifier">t</span><span class="special">(</span><span class="identifier">my_func</span><span class="special">);</span> <span class="identifier">t</span><span class="special">.</span><span class="identifier">detach</span><span class="special">();</span> <span class="special">}</span> </pre> </div> <div class="section"> <div class="titlepage"><div><div><h4 class="title"> <a name="thread.thread_management.tutorial.join"></a><a class="link" href="thread_management.html#thread.thread_management.tutorial.join" title="Joining a thread">Joining a thread</a> </h4></div></div></div> <p> In order to wait for a thread of execution to finish, the <a class="link" href="thread_management.html#thread.thread_management.thread.join" title="Member function join()"><code class="computeroutput"><span class="identifier">join</span><span class="special">()</span></code></a>, __join_for or __join_until ( <a class="link" href="thread_management.html#thread.thread_management.thread.timed_join" title="Member function timed_join() DEPRECATED"><code class="computeroutput"><span class="identifier">timed_join</span><span class="special">()</span></code></a> deprecated) member functions of the <a class="link" href="thread_management.html#thread.thread_management.thread" title="Class thread"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span></code></a> object must be used. <a class="link" href="thread_management.html#thread.thread_management.thread.join" title="Member function join()"><code class="computeroutput"><span class="identifier">join</span><span class="special">()</span></code></a> will block the calling thread until the thread represented by the <a class="link" href="thread_management.html#thread.thread_management.thread" title="Class thread"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span></code></a> object has completed. </p> <pre class="programlisting"><span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span> <span class="identifier">t</span><span class="special">(</span><span class="identifier">my_func</span><span class="special">);</span> <span class="identifier">t</span><span class="special">.</span><span class="identifier">join</span><span class="special">();</span> <span class="special">}</span> </pre> <p> If the thread of execution represented by the <a class="link" href="thread_management.html#thread.thread_management.thread" title="Class thread"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span></code></a> object has already completed, or the <a class="link" href="thread_management.html#thread.thread_management.thread" title="Class thread"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span></code></a> object represents <span class="emphasis"><em>Not-a-Thread</em></span>, then <a class="link" href="thread_management.html#thread.thread_management.thread.join" title="Member function join()"><code class="computeroutput"><span class="identifier">join</span><span class="special">()</span></code></a> returns immediately. </p> <pre class="programlisting"><span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span> <span class="identifier">t</span><span class="special">;</span> <span class="identifier">t</span><span class="special">.</span><span class="identifier">join</span><span class="special">();</span> <span class="comment">// do nothing</span> <span class="special">}</span> </pre> <p> Timed based join are similar, except that a call to __join_for or __join_until will also return if the thread being waited for does not complete when the specified time has elapsed or reached respectively. </p> <pre class="programlisting"><span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span> <span class="identifier">t</span><span class="special">;</span> <span class="keyword">if</span> <span class="special">(</span> <span class="identifier">t</span><span class="special">.</span><span class="identifier">join_for</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">milliseconds</span><span class="special">(</span><span class="number">500</span><span class="special">))</span> <span class="special">)</span> <span class="comment">// do something else</span> <span class="identifier">t</span><span class="special">.</span><span class="identifier">join</span><span class="special">();</span> <span class="comment">// join anyway</span> <span class="special">}</span> </pre> </div> <div class="section"> <div class="titlepage"><div><div><h4 class="title"> <a name="thread.thread_management.tutorial.destructor1"></a><a class="link" href="thread_management.html#thread.thread_management.tutorial.destructor1" title="Destructor V1">Destructor V1</a> </h4></div></div></div> <p> When the <a class="link" href="thread_management.html#thread.thread_management.thread" title="Class thread"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span></code></a> object that represents a thread of execution is destroyed the thread becomes <span class="emphasis"><em>detached</em></span>. Once a thread is detached, it will continue executing until the invocation of the function or callable object supplied on construction has completed, or the program is terminated. A thread can also be detached by explicitly invoking the <a class="link" href="thread_management.html#thread.thread_management.thread.detach" title="Member function detach()"><code class="computeroutput"><span class="identifier">detach</span><span class="special">()</span></code></a> member function on the <a class="link" href="thread_management.html#thread.thread_management.thread" title="Class thread"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span></code></a> object. In this case, the <a class="link" href="thread_management.html#thread.thread_management.thread" title="Class thread"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span></code></a> object ceases to represent the now-detached thread, and instead represents <span class="emphasis"><em>Not-a-Thread</em></span>. </p> </div> <div class="section"> <div class="titlepage"><div><div><h4 class="title"> <a name="thread.thread_management.tutorial.destructor2"></a><a class="link" href="thread_management.html#thread.thread_management.tutorial.destructor2" title="Destructor V2">Destructor V2</a> </h4></div></div></div> <p> When the <a class="link" href="thread_management.html#thread.thread_management.thread" title="Class thread"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span></code></a> object that represents a thread of execution is destroyed the program terminates if the thread is __joinable__. </p> <pre class="programlisting"><span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span> <span class="identifier">t</span><span class="special">(</span><span class="identifier">my_func</span><span class="special">);</span> <span class="special">}</span> <span class="comment">// calls std::terminate()</span> </pre> <p> You can use a thread_joiner to ensure that the thread has been joined at the thread destructor. </p> <pre class="programlisting"><span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span> <span class="identifier">t</span><span class="special">(</span><span class="identifier">my_func</span><span class="special">);</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread_joiner</span> <span class="identifier">g</span><span class="special">(</span><span class="identifier">t</span><span class="special">);</span> <span class="comment">// do someting else</span> <span class="special">}</span> <span class="comment">// here the thread_joiner destructor will join the thread before it is destroyed.</span> </pre> </div> <div class="section"> <div class="titlepage"><div><div><h4 class="title"> <a name="thread.thread_management.tutorial.interruption"></a><a class="link" href="thread_management.html#thread.thread_management.tutorial.interruption" title="Interruption">Interruption</a> </h4></div></div></div> <p> A running thread can be <span class="emphasis"><em>interrupted</em></span> by invoking the <a class="link" href="thread_management.html#thread.thread_management.thread.interrupt" title="Member function interrupt() EXTENSION"><code class="computeroutput"><span class="identifier">interrupt</span><span class="special">()</span></code></a> member function of the corresponding <a class="link" href="thread_management.html#thread.thread_management.thread" title="Class thread"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread</span></code></a> object. When the interrupted thread next executes one of the specified <a class="link" href="thread_management.html#interruption_points"><span class="emphasis"><em>interruption points</em></span></a> (or if it is currently <span class="emphasis"><em>blocked</em></span> whilst executing one) with interruption enabled, then a <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread_interrupted</span></code> exception will be thrown in the interrupted thread. If not caught, this will cause the execution of the interrupted thread to terminate. As with any other exception, the stack will be unwound, and destructors for objects of automatic storage duration will be executed. </p> <p> If a thread wishes to avoid being interrupted, it can create an instance of <a class="link" href="thread_management.html#thread.thread_management.this_thread.disable_interruption" title="Class disable_interruption EXTENSION"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">this_thread</span><span class="special">::</span><span class="identifier">disable_interruption</span></code></a>. Objects of this class disable interruption for the thread that created them on construction, and restore the interruption state to whatever it was before on destruction: </p> <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">f</span><span class="special">()</span> <span class="special">{</span> <span class="comment">// interruption enabled here</span> <span class="special">{</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">this_thread</span><span class="special">::</span><span class="identifier">disable_interruption</span> <span class="identifier">di</span><span class="special">;</span> <span class="comment">// interruption disabled</span> <span class="special">{</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">this_thread</span><span class="special">::</span><span class="identifier">disable_interruption</span> <span class="identifier">di2</span><span class="special">;</span> <span class="comment">// interruption still disabled</span> <span class="special">}</span> <span class="comment">// di2 destroyed, interruption state restored</span> <span class="comment">// interruption still disabled</span> <span class="special">}</span> <span class="comment">// di destroyed, interruption state restored</span> <span class="comment">// interruption now enabled</span> <span class="special">}</span> </pre> <p> The effects of an instance of <a class="link" href="thread_management.html#thread.thread_management.this_thread.disable_interruption" title="Class disable_interruption EXTENSION"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">this_thread</span><span class="special">::</span><span class="identifier">disable_interruption</span></code></a> can be temporarily reversed by constructing an instance of <a class="link" href="thread_management.html#thread.thread_management.this_thread.restore_interruption" title="Class restore_interruption EXTENSION"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">this_thread</span><span class="special">::</span><span class="identifier">restore_interruption</span></code></a>, passing in the <a class="link" href="thread_management.html#thread.thread_management.this_thread.disable_interruption" title="Class disable_interruption EXTENSION"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">this_thread</span><span class="special">::</span><span class="identifier">disable_interruption</span></code></a> object in question. This will restore the interruption state to what it was when the <a class="link" href="thread_management.html#thread.thread_management.this_thread.disable_interruption" title="Class disable_interruption EXTENSION"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">this_thread</span><span class="special">::</span><span class="identifier">disable_interruption</span></code></a> object was constructed, and then disable interruption again when the <a class="link" href="thread_management.html#thread.thread_management.this_thread.restore_interruption" title="Class restore_interruption EXTENSION"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">this_thread</span><span class="special">::</span><span class="identifier">restore_interruption</span></code></a> object is destroyed. </p> <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">g</span><span class="special">()</span> <span class="special">{</span> <span class="comment">// interruption enabled here</span> <span class="special">{</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">this_thread</span><span class="special">::</span><span class="identifier">disable_interruption</span> <span class="identifier">di</span><span class="special">;</span> <span class="comment">// interruption disabled</span> <span class="special">{</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">this_thread</span><span class="special">::</span><span class="identifier">restore_interruption</span> <span class="identifier">ri</span><span class="special">(</span><span class="identifier">di</span><span class="special">);</span> <span class="comment">// interruption now enabled</span> <span class="special">}</span> <span class="comment">// ri destroyed, interruption disable again</span> <span class="special">}</span> <span class="comment">// di destroyed, interruption state restored</span> <span class="comment">// interruption now enabled</span> <span class="special">}</span> </pre> <p> At any point, the interruption state for the current thread can be queried by calling <a class="link" href="thread_management.html#thread.thread_management.this_thread.interruption_enabled" title="Non-member function interruption_enabled() EXTENSION"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">this_thread</span><span class="special">::</span><span class="identifier">interruption_enabled</span><span class="special">()</span></code></a>. </p> <a name="interruption_points"></a><h6> <a name="thread.thread_management.tutorial.interruption.h0"></a> <span class="phrase"><a name="thread.thread_management.tutorial.interruption.predefined_interruption_points"></a></span><a class="link" href="thread_management.html#thread.thread_management.tutorial.interruption.predefined_interruption_points">Predefined Interruption Points</a> </h6> <p> The following functions are <span class="emphasis"><em>interruption points</em></span>, which will throw <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">thread_interrupted</span></code> if interruption is enabled for the current thread, and interruption is requested for the current thread: </p> <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> <li class="listitem"> <a class="link" href="thread_management.html#thread.thread_management.thread.join" title="Member function join()"><code class="computeroutput"><span class="identifier">boost</span><s