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.
Related
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.
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.)
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.
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?
I have the .exe of a program which has been generated from C++.
Is there some simple snippet which I could just insert to get the time taken by the program. I have the C++ code available but I don't want to tweak it much.
Read about Boost.Timers. Code sample to measure time will be:
#include <boost/timer/timer.hpp>
boost::timer t0;
// do smth
std::cout<<"elapsed: "<< t0.elapsed() << " s\n";
A simple way to measure the time taken by some part (or all) of your program is to take a snapshot of the current time at the start and then subtract it from the current time at the end. On Windows, you could use the GetTickCount function for this. I commonly wrap this in a little helper struct:
struct Duration {
Duration( const char *name )
: m_start( ::GetTickCount() ),
m_name( name )
{ }
~Duration() {
std::cout << m_name << " executed in " << ::GetTickCount() - start << "ms" << std::endl;
}
const DWORD m_start;
const std::string m_name;
};
You can use it like this:
int main()
{
Duration d( "Program" );
// Heavy work being done here
}
A little timing information is printed to stdout as the Duration object is destroyed.
On unix you would just need to prefix the executable command with "time", and if you by chance have Cygwin installed, then that's what I what suggest to use. Otherwise check Performance Counters, which is the very source of the process performance data on MS platform. It should be possible to do the trick with a pain of one extra method call before the app exit.