prevent sleep_for from blocking background thread - c++

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.)

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.

C++ condition variable with no time out

Recently, I met a problem which is related with condition variable in C++. The code is shown below :
#include <iostream>
#include <thread>
#include <chrono>
#include <mutex>
#include <condition_variable>
std::condition_variable cv;
std::mutex mutex;
int main(){
std::unique_lock<std::mutex> uniqueLock(mutex);
while (true)
{
if(cv.wait_for(uniqueLock, std::chrono::milliseconds(1000)) == std::cv_status::no_timeout)
{
std::cout << "has image" << std::endl;
}
else
{
std::cout<< "time out " << std::endl;
}
}
return 0;
}
The goal of this code is that : each time when condition variable is notified in another thread (cv.notify()), it show "has image " in the console, and if it can not be notified more than 1000 milliseconds, it shows "time out".
So the theoretical output of the above code is (because the condition variable is not notified) :
time out
time out
time out
time out
But when i execute this code in the Vs2015, I found that the output is strange:
has image
time out
has image
time out
time out
time out
has image
has image
time out
time out
time out
time out
time out
has image
has image
I would like to know why i have this output and how can i achieve my goal
Thanks !
I don't know what the cause of your error is (but there are some plausible explanations in the comments). However, one way to fix your issue is to use the other overload of wait_for, which includes a predicate.
It could look something like this (hasImage is just a bool here, replace it with something that makes sense for your needs - !imageStorage.empty() or similar):
while (true)
{
if (cv.wait_for(uniqueLock, std::chrono::milliseconds(1000), []() {return hasImage;}))
{
std::cout << "has image" << std::endl;
hasImage = false;
}
else
{
std::cout << "time out " << std::endl;
}
}
The pertinent point is that the predicate checks if there actually is a new image, and if there isn't then it should continue to wait.
One limitation with this method is that, if the predicate returns false (no image), then you don't know if the condition variable woke due to a spurious wakeup, a timeout, or if there actually was an image but another thread just took it away before this one woke up. But if that is something your design can handle, then this variation works very well.

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

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.

C++ pointer to function [raspberry pi]

I'm trying to change a code written in C++ and run it on Raspberry Pi. It is an opensource code called freelss (https://github.com/hairu/freelss) and it's a laser scanner software. I tried to change some parts. For example, I expanded the system with some i2c chips and some buttons. Now I have changed the main.cpp and the main.h to scan the buttons. Everything works fine but now I wanted to have a button that starts the scanning process if I push it.
Scanner (*scanner_Max);
std::cout << "before the first function" << std::endl;
scanner_Max->setTask(Scanner::GENERATE_SCAN);
std::cout << "after the first function" << std::endl;
Now, if I push the button, It says "before the first function" goes into the setTask function and stays there. It never comes back. So I never get the message "after the first function".
void Scanner::setTask(Scanner::Task task)
{
std::cout << "setTask starts" << std::endl;
m_task = task;
}
This is the function in scanner.cpp. I always get the "setTask starts" but it won't come back to the main programm. Can please someone help me with the code?
Greets, Max
In the code you have shown you have not created an instance of Scanner, just a pointer.
Are you missing a:
scanner_Max = new Scanner ();
Or have you just not shown this?

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.