libqi provides a threadpool for doing small asynchronous operations. Note that blocking in these threads impacts the whole system as a non-working thread will prevent other work from being scheduled.
You can push a task to be executed asynchronously from a simple C++ function. It is also possible to specify a delay for the task.
#include <qi/application.hpp>
#include <qi/eventloop.hpp>
void doSomething(int value) {
std::cout << "value is " << value << std::endl;
}
int main(int argc, char* argv[]) {
qi::Application app(argc, argv);
// run as soon as possible
qi::Future<void> future = qi::async(boost::bind(doSomething, 42));
// run in 2 seconds
qi::Future<void> future2 = qi::async(boost::bind(doSomething, 42), 2000000);
// do stuff...
future.wait();
future2.wait();
return 0;
}
If your function should be called periodically, use qi::PeriodicTask
.
It is also possible to cancel the execution of a task if it hasn’t started yet:
qi::Future<void> future = qi::async(boost::bind(doSomething, 42), 2000000);
future.cancel();
// doSomething will never be called
There are two ways of using an AnyObject asynchronously, with the async()
method and the qi::async()
function.
qi::AnyObject tts = session.service("ALTextToSpeech");
qi::AnyObject motion = session.service("ALMotion");
qi::Future<void> sayOp = qi::async(tts, "say", "This is a very very very very long sentence.");
qi::Future<void> moveOp = motion.async("moveTo", 1, 0, 0);
// Wait for both operations to terminate.
sayOp.wait();
moveOp.wait();
There is another way of doing async with AnyObjects:
tts.post("say", "Yes!");
post()
does not return a future, it just posts a call and discards the return
value. This is close to calling async()
but is a bit faster (and spare a
message when using remote sessions) because no future is created and the return
value is discarded very early. Use it whenever you can when you don’t need the
future from async
.
Look at the qi::Future
for more complete documentation, but here is what you
most definitely need to know:
The callbacks connected to the qi::Future
will also be called from the
threadpool.
void callback() {
std::cout << "I'm called from a thread" << std::endl;
}
qi::Promise<void> promise;
qi::Future<void> future = promise.future();
future.connect(callback);
promise.setValue(0);