Task executed with std::async is blocking like if future was used - c++

I am having a hard time understanding why following code blocks:
{
std::async(std::launch::async, [] { std::this_thread::sleep_for(5s);
// this line will not execute until above task finishes?
}
I suspect that std::async returns std::future as temporary which in destructor joins on the task thread. Is it possible?
Full code is below:
int main() {
using namespace std::literals;
{
auto fut1 = std::async(std::launch::async, [] { std::this_thread::sleep_for(5s); std::cout << "work done 1!\n"; });
// here fut1 in its destructor will force a join on a thread associated with above task.
}
std::cout << "Work done - implicit join on fut1 associated thread just ended\n\n";
std::cout << "Test 2 start" << std::endl;
{
std::async(std::launch::async, [] { std::this_thread::sleep_for(5s); std::cout << "work done 2!" << std::endl; });
// no future so it should not join - but - it does join somehow.
}
std::cout << "This shold show before work done 2!?" << std::endl;
}

Yes, std::future returned by async has the special property of waiting for the task to be completed in the destructor.
This is because loose threads are bad news, and the only token you have to wait for that thread is in the destructor of the future.
To fix this, store the resulting futures until either you need the result to be done, or in extreme cases the end of the program.
Writing your own thread pool system is also a good idea; I find C++ threading primitives to be sufficient to write a threading system, but use in the raw is not something I'd encourage outside of tiny programs.

Related

Do you need to store the std::future return value from std::async?

Consider the follow code:
#include <iostream>
#include <future>
#include <thread>
#include <chrono>
void func()
{
std::async(std::launch::async, []{std::this_thread::sleep_for(std::chrono::milliseconds(1000)); });
}
int main()
{
std::cout << "start " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count() << "ms\n";
func();
std::cout << "stop " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count() << "ms\n";
return 0;
}
outputs:
start 18737230ms
stop 18738230ms
We can see that 1 seconds passes before func() returns. However there is no std::future stored from std::async(...); - i.e.: auto f = std::async(...)
This appears to work - but I am wandering what the mechanism is such that this works. If I have a std::future (auto f in my little example) then when it goes out of scope it tidies up the thread - i.e. waits for 1 second and then the thread is disposed of behind the scenes.
A further test:
int main() {
std::cout << "start " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count() << "ms\n";
std::async(std::launch::async, []{std::this_thread::sleep_for(std::chrono::milliseconds(1000)); });
std::cout << "stop1 " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count() << "ms\n";
auto f = std::async(std::launch::async, []{std::this_thread::sleep_for(std::chrono::milliseconds(1000)); });
std::cout << "stop2 " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count() << "ms\n";
return 0;
}
gives:
start 4448133ms
stop1 4449133ms - 1 sec passed
stop2 4449133ms - almost no time passed
So this shows that storing the future, means that the thread runs parallel. Not storing the future means the thread appears to have to run to completion - I guess this is because a temporary future is created and destroyed?
So my conclusion is that you can't just call std::async(...) without storing the std::future if you want it to run in parallel (which is the whole point) - even if you don't plan to use the future.
hmm... I think I have just talked myself into the answer! - but I am not 100% sure I have the reasoning correct - hopefully I have...
If the std::future is created via std::async, the destructor waits for end of the task. This does not mean that the task does not run in parallel - it just waits for the end of the task at the end of scope of variable. Yet it makes usage of std::async without storing a std::future a bit tricky and I would generally recommend storing the future somewhere to avoid nasty surprises. Take a look at page about std::future destructor (emphasis mine):
these actions will not block for the shared state to become ready, except that it may block if all of the following are true: the shared state was created by a call to std::async, the shared state is not yet ready, and this was the last reference to the shared state.

Deadlock using std::mutex to protect cout in multiple threads

Using cout in multiple threads might result in interleaved output.
So I tried to protect cout with a mutex.
The following code starts 10 background threads with std::async. When a thread starts, it prints "Started thread ...".
The main thread iterates over the futures of the background threads in the order in which they were created and prints out "Done thread ..." when the corresponding thread finished.
The output is synchronized correctly, but after some threads have started and some have finished (see output below), a deadlock occurres. All background threads left and the main thread are waiting for the mutex.
What is the reason for the deadlock?
When the print function is left or one iteration of the for loop ends, the lock_guard should unlock the mutex, so that one of the waiting threads would be able to proceed.
Why are all the threads left starving?
Code
#include <future>
#include <iostream>
#include <vector>
using namespace std;
std::mutex mtx; // mutex for critical section
int print_start(int i) {
lock_guard<mutex> g(mtx);
cout << "Started thread" << i << "(" << this_thread::get_id() << ") " << endl;
return i;
}
int main() {
vector<future<int>> futures;
for (int i = 0; i < 10; ++i) {
futures.push_back(async(print_start, i));
}
//retrieve and print the value stored in the future
for (auto &f : futures) {
lock_guard<mutex> g(mtx);
cout << "Done thread" << f.get() << "(" << this_thread::get_id() << ")" << endl;
}
cin.get();
return 0;
}
Output
Started thread0(352)
Started thread1(14944)
Started thread2(6404)
Started thread3(16884)
Done thread0(16024)
Done thread1(16024)
Done thread2(16024)
Done thread3(16024)
Your problem lies in the use of future::get:
Returns the value stored in the shared state (or throws its exception)
when the shared state is ready.
If the shared state is not yet ready (i.e., the provider has not yet
set its value or exception), the function blocks the calling thread
and waits until it is ready.
http://www.cplusplus.com/reference/future/future/get/
So if the thread behind the future didn't get to run yet, the function blocks until that thread finishes. However, you take ownership of the mutex before calling future::get, so whichever thread you're waiting for will not be able to attain the mutex for itself.
This should fix your deadlock problem:
int value = f.get();
lock_guard<mutex> g(mtx);
cout << "Done thread" << value << "(" << this_thread::get_id() << ")" << endl;
You lock the mutex and then wait for one of the futures, which in turn requires a lock on the mutex itself. Simple rule: Don't wait with locked mutexes.
BTW: Locking output streams is not very effective, because it can easily be circumvented by code you don't even control. Rather than using those globals, give a stream to code that needs to output something (dependency injection) and then collect the data from that stream in a threadsafe way. Or use a logging library, because that's probably what you wanted to do anyway.
It is good that the reason was spotted from the source. However, quite often the error, as it happens, may be not so easy to locate. And the reason may differ as well. Fortunately, in case of deadlock you can use debugger to investigate it.
I compiled and ran your example, then after attaching to it with gdb (gcc 4.9.2/Linux), there is a backtrace (noisy implementation details skipped):
#0 __lll_lock_wait ()
...
#5 0x0000000000403140 in std::lock_guard<std::mutex>::lock_guard (
this=0x7ffe74903320, __m=...) at /usr/include/c++/4.9/mutex:377
#6 0x0000000000402147 in print_start (i=0) at so_deadlock.cc:9
...
#23 0x0000000000409e69 in ....::_M_complete_async() (this=0xdd4020)
at /usr/include/c++/4.9/future:1498
#24 0x0000000000402af2 in std::__future_base::_State_baseV2::wait (
this=0xdd4020) at /usr/include/c++/4.9/future:321
#25 0x0000000000404713 in std::__basic_future<int>::_M_get_result (
this=0xdd47e0) at /usr/include/c++/4.9/future:621
#26 0x0000000000403c48 in std::future<int>::get (this=0xdd47e0)
at /usr/include/c++/4.9/future:700
#27 0x000000000040229b in main () at so_deadlock.cc:24
This is just what is explained in the other answers - the code in locked section (so_deadlock.cc:24) calls future::get(), which in turn (by forcing the result) trying to acquire the lock again.
It might be not that simple in other cases, there are usually several threads, but it's all there.

prevent sleep_for from blocking background thread

I'm writing in pure c++11 and want to do a simple 'wait x seconds and turn on a member variable' after turning it off. The member variable of the class in this example is a flag for 'animating'.
cout << "stop animating!" << endl;
this->animating = false;
async(launch::async, [this] ()
{
this_thread::sleep_for(chrono::seconds{8});
this->animating = true;
std::cout << "start animating!" << std::endl;
});
cout << "i'm here" << endl;
the this_thread::sleep_for blocks the entire program from continuing on (even though it is inside an async thread). because i dont see "I'm here" 8 seconds later. If the above code worked as intended, i would see "I'm here" immediately after "stop animating". This blocking is a problem for me because it locks up everything I care about like continuing to process 'input' like keyboard events, and the program also stops 'drawing' other objects on the screen.
Does anyone know how to achieve a simple delayed and async change of a member variable using standard c++11 (no frameworks like boost please)
in iOS it is very simple:
// Delay execution of my block for 10 seconds.
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 10 * NSEC_PER_SEC),
dispatch_get_main_queue(), ^
{
//do whatever, 10 seconds later
});
As per #user2176127 's comment - have you tried this? :
cout << "stop animating!" << endl;
this->animating = false;
std::thread delay_thread(
[this]() {
this_thread::sleep_for(chrono::seconds{8});
this->animating = true;
std::cout << "start animating!" << std::endl;
}
);
delay_thread.detach();
std::cout << "I'm here" << std::endl;
Also note you likely need to wrap the animating member in an std::atomic<>, i.e. if it was bool it now becomes an std::atomic<bool>, so as to ensure your main thread notices the change when it actually happens. (Using volatile won't help.)

How to stop a function from running from outside in c++

I want to run a function and tell if the function didn't finish after n milliseconds, stop that function and start another one. something like this code:
void run()
{
//do something that doesn't have while(1)
}
void main()
{
run();
if(runFunctionDidntFinishInSeconds(10)
{
endPrintFunction();
backupPlan();
}
return 0;
}
I searched out and found boost::timed_join function. here's my code:
void run()
{
int a;
for (int i = 0; i < 2000; i++)
cout << i << endl;
}
int main()
{
boost::thread t = new boost::thread(&run);
if (t.timed_join(boost::posix_time::microseconds(10000))){
cout << "done" << endl;
}
else{
cout << endl << "not done" << endl;
}
system("pause");
return 0;
}
but it doesn't stop thread 't' from running. I went to terminate the thread, but it's not a good option.
I want the 'a' function to finish the exact time I'm telling it to.
The system gets input every 16ms and I want to do a processing on it and say if the processing took more than about 13ms leave it and go do a backup plan. and I want it to be abstracted from the ones who write the processing method. So putting a while loop on the top of it brings me delay.
What should i do?
The least I think I need is to be abled to reset the processing thread to do what it had needed to do again!
I think your are looking for something like std::future.
http://en.cppreference.com/w/cpp/thread/future/wait_for
You can start the function in another thread and wait until the function returns or has a timeout.
For your example:
std::future< void > future = std::async( std::launch::async, print );
auto status = future.wait_for( std::chrono::seconds( 10 ) );
if ( status == std::future_status::deferred )
{
std::cout << "deferred\n";
}
else if ( status == std::future_status::timeout )
{
std::cout << "timeout\n";
}
else if ( status == std::future_status::ready )
{
std::cout << "ready!\n";
}
However this doesn't cause the detached thread to end. For this it is necessary to include a flag on startup, so the detached thread can cleanup and exit savely on its own.
void run(const std::atomic_bool& cancelled)
{
int a;
for (int i = 0; i < 2000; i++)
{
cout << i << endl;
if (cancelled)
return;
}
}
std::atomic_bool cancellation_token = false;
std::future< void > future = std::async( std::launch::async,
run,
std::ref(cancellation_token) );
auto status = future.wait_for( std::chrono::seconds( 10 ) );
if ( status == std::future_status::deferred )
{
std::cout << "deferred\n";
}
else if ( status == std::future_status::timeout )
{
std::cout << "timeout\n";
cancellation_token = true;
}
else if ( status == std::future_status::ready )
{
std::cout << "ready!\n";
}
I want it to be abstracted from the ones who write the processing method.
Standard C++ does not have a way to forcibly interrupt the control flow of a function from outside of that function's call graph (a function it calls can throw, but someone can't throw for them).
OS-specific thread systems have ways to terminate a thread. However, this leaves the program potentially in an undefined state, as the destructors for any stack variables have not been called. And since you didn't know where it was in that processing when you killed it, you can't effectively clean up after it. Even a C program cannot guarantee that an arbitrary function can be terminated; it would have to be one which did not dynamically allocate memory or other resources that have to be cleaned up.
You can compensate for this by coding your function very carefully. But that requires that the person who wrote that function to code it very carefully. And thus, there isn't an abstraction, since the person writing the function has to know what the rules are and is required to follow them.
So the only solution that works requires cooperation. The function must either be written in such a way that it can safely be stopped via those OS-dependent features, or it must be written to periodically check some value and stop itself.
Here are two and 3/4 approaches.
The first requires that the code you want to halt cooperates. It either polls some variable while it runs, or it calls a function periodically that could throw an exception to halt execution. boost interruptable threads follow the second model.
The second requires you to launch a new process, marshall your data over to the function, and use IPC to get the information back. If the function doesn't return in time, you kill the child process.
The third "half" involves rewriting the code in a different language, or using C++ as a scripting language. You run the code in an interpreter that does the first or second solution for you.
Now, a practical alternative (a 1/4 solution) is to make sure the function is purely functional, run it in a separate thread with a semi-reliable abort message (like the first one), and discard its return value if it takes too long. This doesn't do what you want, but is far easier.
There's a way with atomics used as semaphores but this will emit full blown memory barriers and thus decrease the performance because of the load every iteration :
#include <iostream>
#include <thread>
#include <chrono>
#include <atomic>
std::atomic<bool> printFinished { false };
std::atomic<bool> shouldPrintRun { true };
void print()
{
while (shouldPrintRun.load() /* && your normal stop condition*/)
{
//work..
}
printFinished.store(true);
}
int main()
{
std::thread t(print);
std::this_thread::sleep_for(std::chrono::seconds(10));
if (!printFinished.load())
{
shouldPrintRun.store(false);
t.join();
std::cout << "help!";
}
return 0;
}
If you don't want your function that's ran on another thread to check back if it needs to stop then terminating that thread is the only option.
A possible solution is that you have to make that the lengthy function into small & short incremental function which will continue the task still every time it is call from the last time it left of. The code below which can be run in a thread will do similar job of a time slicer and can be terminated at will.
void Process()
{
bool flag = true;
while (running)
{
std::chrono::high_resolution_clock::time_point time1 = std::chrono::high_resolution_clock::now();
std::chrono::milliseconds span(16);
while ( (std::chrono::high_resolution_clock::now() - time1 ) < span)
{
flag ? incremental_function1() : incremental_function2();
if (!running) return;
}
flag = (!flag);
}
}

How to make a re-entrant Boost coroutine?

I'm using Boost coroutine library, and I need my coroutine to be re-entrant.
This means I should be able to start the coroutine from the beginning multiple times.
What are some options?
My current workaround is to re-create the fresh coroutine every time:
boost::coroutines::coroutine<int>::pull_type *source = new boost::coroutines::coroutine<int>::pull_type(
[&](boost::coroutines::coroutine<int>::push_type& sink){
sink(0);
cout << "Hello world!" << endl;
});
(*source)();
source = new boost::coroutines::coroutine<int>::pull_type(
[&](boost::coroutines::coroutine<int>::push_type& sink){
sink(0);
cout << "Hello world!" << endl;
});
(*source)();
source = new boost::coroutines::coroutine<int>::pull_type(
[&](boost::coroutines::coroutine<int>::push_type& sink){
sink(0);
cout << "Hello world!" << endl;
});
(*source)();
Because the coroutines from boost.coroutine are stackfull you can't start them multiple times.
It is not clear from your example what you want to do:
print "Hello world!" mutiple times -> use a loop inside the coro-fn
some kind of backtracking/checkpointing -> could be done with coroutiens, but needs some additional work
I don't at all see what's wrong with creating a fresh coroutine every time - they're not expensive to create.
If you have a lot of data in your coroutine so it's expensive to construct, move it all off into some data class and pass a reference to it to your coroutine.