Note that there are some explanatory texts on larger screens.

plurals
  1. POAccess to callable object inside an async task conflicts with use of std::cin
    text
    copied!<pre><code>#include &lt;iostream&gt; #include &lt;functional&gt; #include &lt;future&gt; #include &lt;tchar.h&gt; void StartBackground(std::function&lt;void()&gt; notify) { auto background = std::async([&amp;] { notify(); // (A) }); } int _tmain(int argc, _TCHAR* argv[]) { StartBackground([](){}); char c; std::cin &gt;&gt; c; // (B) while (1); return 0; } </code></pre> <p>1) Build and run the code above using Visual Studio 2012.</p> <p>2) Line (A) triggers an Access Violation in <code>_VARIADIC_EXPAND_P1_0(_CLASS_FUNC_CLASS_0, , , , )</code>:</p> <blockquote> <p>First-chance exception at 0x0F96271E (msvcp110d.dll) in ConsoleApplication1.exe: 0xC0000005: Access violation writing location 0x0F9626D8</p> </blockquote> <p>Most confusingly, the exception can be avoided by removing line (B).</p> <h2>Questions</h2> <ul> <li>Why does the callable object <code>notify</code> apparently conflict with the use of <code>std::cin</code>?</li> <li>What's wrong with this code?</li> </ul> <p>The real world scenario for this simplified example is a function that executes some code in parallel and have that code call a user-supplied notify function when done.</p> <h2>Edit</h2> <p>I found at least one problem im my code: The <code>background</code> variable is destroyed as soon as <code>StartBackground()</code> exits. Since <code>std::async</code> may or may not start a separate thread, and <code>std::thread</code> calls <code>terminate()</code> if the thread is still joinable, this might be causing the problem. The following variant works because it gives the task enough time to complete:</p> <pre><code>void StartBackground(std::function&lt;void()&gt; notify) { auto background = std::async([&amp;] { notify(); // (A) }); std::this_thread::sleep_for(std::chrono::seconds(1)); } </code></pre> <p>Keeping the <code>std::future</code> object alive over a longer period instead of sleeping should also work. But the following code also causes the same access violation:</p> <pre><code>std::future&lt;void&gt; background; void StartBackground(std::function&lt;void()&gt; notify) { background = std::async([&amp;] { notify(); // (A) }); } </code></pre> <p>whereas using a <code>std::thread</code> in the same manner works as expected:</p> <pre><code>std::thread background; void StartBackground(std::function&lt;void()&gt; notify) { background = std::thread([&amp;] { notify(); // (A) }); } </code></pre> <p>I'm completely puzzled. I must be missing some very crucial points here regarding <code>std::async</code> and <code>std::thread</code>.</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