Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Indeed, there is a race condition between the destructor of the local <code>promise</code> object (at the end of the constructor and the call to <code>set_value()</code> from the thread. That is, <code>set_value()</code> wakes the main tread, that just next destroys the promise object, but the <code>set_value()</code> function has not yet finished, and dead-locks.</p> <p>Reading the C++11 standard, I'm not sure if your use is allowed:</p> <blockquote> <p><code>void promise&lt;void&gt;::set_value();</code></p> <p>Effects: atomically stores the value r in the shared state and makes that state ready.</p> </blockquote> <p>But somewhere else:</p> <blockquote> <p>The set_value, set_exception, set_value_at_thread_exit, and set_exception_at_thread_exit member functions behave as though they acquire a <strong>single mutex</strong> associated with the promise object while updating the promise object.</p> </blockquote> <p>Are <code>set_value()</code> calls supposed to be atomic with regards to other functions, such as the destructor? </p> <p>IMHO, I'd say no. The effects would be comparable to destroying a mutex while other thread is still locking it. The result is undefined.</p> <p>The solution would be to make <code>p</code> outlive the thread. Two solutions that I can think of:</p> <ol> <li><p>Make <code>p</code> a member of the class, just as Michael Burr suggested in the other answer.</p></li> <li><p>Move the promise into the thread.</p></li> </ol> <p>In the constructor:</p> <pre><code>std::promise&lt;void&gt; p; std::future &lt;void&gt; f = p.get_future(); _thread = std::thread(&amp;foo::run, this, std::move(p)); </code></pre> <p>BTW, you don't need the call to <code>bind</code>, (the thread constructor is already overloaded), or call to <code>std::move</code> to move the thread (the right value is already an r-value). The call to <code>std::move</code> into the promise is mandatory, though.</p> <p>And the thread function does not receive a reference, but the moved promise:</p> <pre><code>void run(std::promise&lt;void&gt; p) { p.set_value(); } </code></pre> <p>I think that this is precisely why C++11 defines two different classes: <code>promise</code> and <code>future</code>: you move the promise into the thread, but you keep the future to recover the result.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload