247 lines
19 KiB
HTML
247 lines
19 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh" dir="ltr" class="client-nojs" xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh">
|
|
<head><meta http-equiv="x-ua-compatible" content="ie=edge">
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
<title>std::promise</title>
|
|
<link rel="stylesheet" href="ext.css" />
|
|
<link rel="stylesheet" href="site_modules.css" />
|
|
</head>
|
|
<body class="mediawiki ltr sitedir-ltr ns-0 ns-subject page-cpp_thread_promise skin-cppreference2 action-view cpp-navbar">
|
|
<div id="cpp-content-base">
|
|
<div id="content"><a id="top"></a>
|
|
<h1 id="firstHeading" class="firstHeading"><span style="font-size:0.7em; line-height:130%">std::</span>promise</h1>
|
|
<div id="bodyContent">
|
|
<div id="contentSub"><span class="subpages">< <a href="cpp.html">cpp</a>‎ | <a href="cpp-thread.html">thread</a></span></div>
|
|
<div id="mw-content-text" lang="zh" dir="ltr" class="mw-content-ltr" xml:lang="zh">
|
|
<table class="t-dcl-begin">
|
|
<tbody>
|
|
<tr class="t-dsc-header">
|
|
<td>
|
|
<div>定义于头文件 <code><a href="cpp-header-future.html"><future></a></code></div>
|
|
</td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr class="t-dcl t-since-cxx11">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw1">template</span><span class="sy1"><</span> <span class="kw1">class</span> R <span class="sy1">></span> <span class="kw1">class</span> promise<span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(1)</td>
|
|
<td><span class="t-mark-rev t-since-cxx11">(C++11 起)</span></td>
|
|
</tr>
|
|
<tr class="t-dcl t-since-cxx11">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw1">template</span><span class="sy1"><</span> <span class="kw1">class</span> R <span class="sy1">></span> <span class="kw1">class</span> promise<span class="sy1"><</span>R<span class="sy3">&</span><span class="sy1">></span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(2)</td>
|
|
<td><span class="t-mark-rev t-since-cxx11">(C++11 起)</span></td>
|
|
</tr>
|
|
<tr class="t-dcl t-since-cxx11">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw1">template</span><span class="sy1"><></span> <span class="kw1">class</span> promise<span class="sy1"><</span><span class="kw4">void</span><span class="sy1">></span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(3)</td>
|
|
<td><span class="t-mark-rev t-since-cxx11">(C++11 起)</span></td>
|
|
</tr>
|
|
<tr class="t-dcl-sep">
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<div class="t-li1"><span class="t-li">1)</span> 空模板</div>
|
|
<div class="t-li1"><span class="t-li">2)</span> 非 void 特化,用于在线程间交流对象</div>
|
|
<div class="t-li1"><span class="t-li">3)</span> void 特化,用于交流无状态事件</div>
|
|
<p>类模板 <code>std::promise</code> 提供存储值或异常的设施,之后通过 <code>std::promise</code> 对象所创建的 <span class="t-lc"><a href="cpp-thread-future.html">std::future</a></span> 对象异步获得结果。注意 <code>std::promise</code> 只应当使用一次。</p>
|
|
<p>每个 promise 与<i>共享状态</i>关联,共享状态含有一些状态信息和可能仍未求值的<i>结果</i>,它求值为值(可能为 void )或求值为异常。 promise 可以对共享状态做三件事:</p>
|
|
<ul>
|
|
<li><i>使就绪</i>: promise 存储结果或异常于共享状态。标记共享状态为就绪,并解除阻塞任何等待于与该共享状态关联的 future 上的线程。</li>
|
|
<li><i>释放</i>: promise 放弃其对共享状态的引用。若这是最后一个这种引用,则销毁共享状态。除非这是 <span class="t-c"><span class="mw-geshi cpp source-cpp"><a href="cpp-thread-async.html"><span class="kw2183">std::<span class="me2">async</span></span></a></span></span> 所创建的未就绪的共享状态,否则此操作不阻塞。</li>
|
|
<li><i>抛弃</i>: promise 存储以 <span class="t-lc"><a href="cpp-thread-future_errc.html">std::future_errc::broken_promise</a></span> 为 error_code 的 <span class="t-lc"><a href="cpp-thread-future_error.html">std::future_error</a></span> 类型异常,令共享状态为<i>就绪</i>,然后<i>释放</i>它。</li>
|
|
</ul>
|
|
<p>promise 是 promise-future 交流通道的“推”端:存储值于共享状态的操作<i>同步于</i>(定义于 <span class="t-lc"><a href="cpp-atomic-memory_order.html">std::memory_order</a></span> )任何在共享状态上等待的函数(如 <span class="t-lc"><a href="cpp-thread-future-get.html">std::future::get</a></span> )的成功返回。其他情况下对共享状态的共时访问可能冲突:例如, <span class="t-lc"><a href="cpp-thread-shared_future-get.html">std::shared_future::get</a></span> 的多个调用方必须全都是只读,或提供外部同步。</p>
|
|
<h3><span class="mw-headline" id=".E6.88.90.E5.91.98.E5.87.BD.E6.95.B0">成员函数</span></h3>
|
|
<table class="t-dsc-begin">
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div t-dsc-member-nobold-div">
|
|
<div><a href="cpp-thread-promise-promise.html"><span class="t-lines"><span>(构造函数)</span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>构造<code>std::promise</code>对象<br />
|
|
<span class="t-mark">(公开成员函数)</span></td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div t-dsc-member-nobold-div">
|
|
<div><a href="cpp-thread-promise-~promise.html"><span class="t-lines"><span>(析构函数)</span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>析构<code>std::promise</code>对象<br />
|
|
<span class="t-mark">(公开成员函数)</span></td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-thread-promise-operator=.html"><span class="t-lines"><span>operator=</span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>赋值共享状态<br />
|
|
<span class="t-mark">(公开成员函数)</span></td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-thread-promise-swap.html"><span class="t-lines"><span>swap</span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>交换二个 promise 对象<br />
|
|
<span class="t-mark">(公开成员函数)</span></td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="2">
|
|
<h5><span class="mw-headline" id=".E8.8E.B7.E5.8F.96.E7.BB.93.E6.9E.9C">获取结果</span></h5>
|
|
</td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-thread-promise-get_future.html"><span class="t-lines"><span>get_future</span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>返回与承诺的结果关联的 <a href="cpp-thread-future.html"><tt>future</tt></a><br />
|
|
<span class="t-mark">(公开成员函数)</span></td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="2">
|
|
<h5><span class="mw-headline" id=".E8.AE.BE.E7.BD.AE.E7.BB.93.E6.9E.9C">设置结果</span></h5>
|
|
</td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-thread-promise-set_value.html"><span class="t-lines"><span>set_value</span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>设置结果为指定值<br />
|
|
<span class="t-mark">(公开成员函数)</span></td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-thread-promise-set_value_at_thread_exit.html"><span class="t-lines"><span>set_value_at_thread_exit</span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>设置结果为指定值,同时仅在线程退出时分发提醒<br />
|
|
<span class="t-mark">(公开成员函数)</span></td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-thread-promise-set_exception.html"><span class="t-lines"><span>set_exception</span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>设置结果为指示异常<br />
|
|
<span class="t-mark">(公开成员函数)</span></td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-thread-promise-set_exception_at_thread_exit.html"><span class="t-lines"><span>set_exception_at_thread_exit</span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>设置结果为指示异常,同时仅在线程退出时分发提醒<br />
|
|
<span class="t-mark">(公开成员函数)</span></td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E9.9D.9E.E6.88.90.E5.91.98.E5.87.BD.E6.95.B0">非成员函数</span></h3>
|
|
<table class="t-dsc-begin">
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-thread-promise-swap2.html"><span class="t-lines"><span>std::swap<span class="t-dsc-small">(std::promise)</span></span></span></a></div>
|
|
<div><span class="t-lines"><span><span class="t-mark-rev t-since-cxx11">(C++11)</span></span></span></div>
|
|
</div>
|
|
</td>
|
|
<td>特化 <span class="t-lc"><a href="cpp-algorithm-swap.html">std::swap</a></span> 算法<br />
|
|
<span class="t-mark">(函数模板)</span></td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E8.BE.85.E5.8A.A9.E7.B1.BB">辅助类</span></h3>
|
|
<table class="t-dsc-begin">
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-thread-promise-uses_allocator.html"><span class="t-lines"><span>std::uses_allocator<span class="t-dsc-small"><std::promise></span></span></span></a></div>
|
|
<div><span class="t-lines"><span><span class="t-mark-rev t-since-cxx11">(C++11)</span></span></span></div>
|
|
</div>
|
|
</td>
|
|
<td>特化 <span class="t-lc"><a href="cpp-memory-uses_allocator.html">std::uses_allocator</a></span> 类型特征<br />
|
|
<span class="t-mark">(类模板特化)</span></td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E7.A4.BA.E4.BE.8B">示例</span></h3>
|
|
<div class="t-example">
|
|
<p>此示例展示能如何将 <code>promise<int></code> 用作线程间信号。</p>
|
|
<div class="t-example-live-link"></div>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="co2">#include <vector></span>
|
|
<span class="co2">#include <thread></span>
|
|
<span class="co2">#include <future></span>
|
|
<span class="co2">#include <numeric></span>
|
|
<span class="co2">#include <iostream></span>
|
|
<span class="co2">#include <chrono></span>
|
|
|
|
<span class="kw4">void</span> accumulate<span class="br0">(</span><a href="cpp-container-vector.html"><span class="kw1269">std::<span class="me2">vector</span></span></a><span class="sy1"><</span><span class="kw4">int</span><span class="sy1">></span><span class="sy4">::</span><span class="me2">iterator</span> first,
|
|
<a href="cpp-container-vector.html"><span class="kw1269">std::<span class="me2">vector</span></span></a><span class="sy1"><</span><span class="kw4">int</span><span class="sy1">></span><span class="sy4">::</span><span class="me2">iterator</span> last,
|
|
std<span class="sy4">::</span><span class="me2">promise</span><span class="sy1"><</span><span class="kw4">int</span><span class="sy1">></span> accumulate_promise<span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<span class="kw4">int</span> sum <span class="sy1">=</span> <a href="cpp-algorithm-accumulate.html"><span class="kw1651">std::<span class="me2">accumulate</span></span></a><span class="br0">(</span>first, last, <span class="nu0">0</span><span class="br0">)</span><span class="sy4">;</span>
|
|
accumulate_promise.<span class="me1">set_value</span><span class="br0">(</span>sum<span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 提醒 future</span>
|
|
<span class="br0">}</span>
|
|
|
|
<span class="kw4">void</span> do_work<span class="br0">(</span>std<span class="sy4">::</span><span class="me2">promise</span><span class="sy1"><</span><span class="kw4">void</span><span class="sy1">></span> barrier<span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<a href="cpp-thread-sleep_for.html"><span class="kw2149">std::<span class="me2">this_thread</span><span class="sy4">::</span><span class="me2">sleep_for</span></span></a><span class="br0">(</span><a href="cpp-chrono-duration.html"><span class="kw997">std::<span class="me2">chrono</span><span class="sy4">::</span><span class="me2">seconds</span></span></a><span class="br0">(</span><span class="nu0">1</span><span class="br0">)</span><span class="br0">)</span><span class="sy4">;</span>
|
|
barrier.<span class="me1">set_value</span><span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span>
|
|
<span class="br0">}</span>
|
|
|
|
<span class="kw4">int</span> main<span class="br0">(</span><span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<span class="co1">// 演示用 promise<int> 在线程间传递结果。</span>
|
|
<a href="cpp-container-vector.html"><span class="kw1269">std::<span class="me2">vector</span></span></a><span class="sy1"><</span><span class="kw4">int</span><span class="sy1">></span> numbers <span class="sy1">=</span> <span class="br0">{</span> <span class="nu0">1</span>, <span class="nu0">2</span>, <span class="nu0">3</span>, <span class="nu0">4</span>, <span class="nu0">5</span>, <span class="nu0">6</span> <span class="br0">}</span><span class="sy4">;</span>
|
|
std<span class="sy4">::</span><span class="me2">promise</span><span class="sy1"><</span><span class="kw4">int</span><span class="sy1">></span> accumulate_promise<span class="sy4">;</span>
|
|
<a href="cpp-thread-future.html"><span class="kw2179">std::<span class="me2">future</span></span></a><span class="sy1"><</span><span class="kw4">int</span><span class="sy1">></span> accumulate_future <span class="sy1">=</span> accumulate_promise.<span class="me1">get_future</span><span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span>
|
|
<a href="cpp-thread-thread.html"><span class="kw2146">std::<span class="me2">thread</span></span></a> work_thread<span class="br0">(</span>accumulate, numbers.<span class="me1">begin</span><span class="br0">(</span><span class="br0">)</span>, numbers.<span class="me1">end</span><span class="br0">(</span><span class="br0">)</span>,
|
|
std<span class="sy4">::</span><span class="me2">move</span><span class="br0">(</span>accumulate_promise<span class="br0">)</span><span class="br0">)</span><span class="sy4">;</span>
|
|
|
|
<span class="co1">// future::get() 将等待直至该 future 拥有合法结果并取得它</span>
|
|
<span class="co1">// 无需在 get() 前调用 wait()</span>
|
|
<span class="co1">//accumulate_future.wait(); // 等待结果</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"result="</span> <span class="sy1"><<</span> accumulate_future.<span class="me1">get</span><span class="br0">(</span><span class="br0">)</span> <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span><span class="sy4">;</span>
|
|
work_thread.<span class="me1">join</span><span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// wait for thread completion</span>
|
|
|
|
<span class="co1">// 演示用 promise<void> 在线程间对状态发信号</span>
|
|
std<span class="sy4">::</span><span class="me2">promise</span><span class="sy1"><</span><span class="kw4">void</span><span class="sy1">></span> barrier<span class="sy4">;</span>
|
|
<a href="cpp-thread-future.html"><span class="kw2179">std::<span class="me2">future</span></span></a><span class="sy1"><</span><span class="kw4">void</span><span class="sy1">></span> barrier_future <span class="sy1">=</span> barrier.<span class="me1">get_future</span><span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span>
|
|
<a href="cpp-thread-thread.html"><span class="kw2146">std::<span class="me2">thread</span></span></a> new_work_thread<span class="br0">(</span>do_work, std<span class="sy4">::</span><span class="me2">move</span><span class="br0">(</span>barrier<span class="br0">)</span><span class="br0">)</span><span class="sy4">;</span>
|
|
barrier_future.<span class="me1">wait</span><span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span>
|
|
new_work_thread.<span class="me1">join</span><span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<p>输出:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="text source-text">
|
|
<pre class="de1">result=21</pre></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="visualClear"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|