#include <iostream>
#include <functional>
#include <future>
#include <tchar.h>
void StartBackground(std::function<void()> notify)
{
auto background = std::async([&]
{
notify(); // (A)
});
}
int _tmain(int argc, _TCHAR* argv[])
{
StartBackground([](){});
char c; std::cin >> c; // (B)
while (1);
return 0;
}
1) Build and run the code above using Visual Studio 2012.
2) Line (A) triggers an Access Violation in _VARIADIC_EXPAND_P1_0(_CLASS_FUNC_CLASS_0, , , , )
:
First-chance exception at 0x0F96271E (msvcp110d.dll) in ConsoleApplication1.exe: 0xC0000005: Access violation writing location 0x0F9626D8
Most confusingly, the exception can be avoided by removing line (B).
Questions
- Why does the callable object
notify
apparently conflict with the use ofstd::cin
? - What's wrong with this code?
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.
Edit
I found at least one problem im my code: The background
variable is destroyed as soon as StartBackground()
exits. Since std::async
may or may not start a separate thread, and std::thread
calls terminate()
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:
void StartBackground(std::function<void()> notify)
{
auto background = std::async([&]
{
notify(); // (A)
});
std::this_thread::sleep_for(std::chrono::seconds(1));
}
Keeping the std::future
object alive over a longer period instead of sleeping should also work. But the following code also causes the same access violation:
std::future<void> background;
void StartBackground(std::function<void()> notify)
{
background = std::async([&]
{
notify(); // (A)
});
}
whereas using a std::thread
in the same manner works as expected:
std::thread background;
void StartBackground(std::function<void()> notify)
{
background = std::thread([&]
{
notify(); // (A)
});
}
I'm completely puzzled.
I must be missing some very crucial points here regarding std::async
and std::thread
.