I've been writing some javascript and one of the few things I like about the environment is the way it uses promises/futures to make handlers for asynchronous events.
In C++ you have to call .get on a future and it blocks until the result of the future is available but in Javascript you can write .then(fn) and it will call the function when the result is ready. Critically it does this in the same thread as the caller at a later time so there are no thread synchronization issues to worry about, at least not the same ones as in c++.
I'm thinking in c++ something like -
auto fut = asyncImageLoader("cat.jpg");
fut.then([](Image img) { std::cout << "Image is now loaded\n" << image; });
Is there any way to achieve this in c++? Clearly it will need some kind of event queue and event loop to handle dispatching the callbacks. I could probably eventually write the code to do most of this but wanted to see if there was any way to achieve the goal easily using standard facilities.
A .then function for std::future has been proposed for the upcoming C++17 standard.
Boost's implementation of future (which is compliant with the current standard, but provides additional features as extensions) already provides parts of that functionality in newer versions (1.53 or newer).
For a more well-established solution, take a look at the Boost.Asio library, which does allow easy implementation of asynchronous control flows as provided by future.then. Asio's concept is slightly more complicated, as it requires access to a central io_service object for dispatching asynchronous callbacks and requires manual management of worker threads. But in principle this is a very good match for what you asked for.
I don't like c++'s future, so i wrote a promise libraries as javascript here
https://github.com/xhawk18/promise-cpp
/* Convert callback to a promise (Defer) */
Defer myDelay(boost::asio::io_service &io, uint64_t time_ms) {
return newPromise([&io, time_ms](Defer &d) {
setTimeout(io, [d](bool cancelled) {
if (cancelled)
d.reject();
else
d.resolve();
}, time_ms);
});
}
void testTimer(io_service &io) {
myDelay(io, 3000).then([&] {
printf("timer after 3000 ms!\n");
return myDelay(io, 1000);
}).then([&] {
printf("timer after 1000 ms!\n");
return myDelay(io, 2000);
}).then([] {
printf("timer after 2000 ms!\n");
}).fail([] {
printf("timer cancelled!\n");
});
}
int main() {
io_service io;
testTimer(io);
io.run();
return 0;
}
compare with Javascript promise, just --
Use newPromise instead of js's new Promise
Use lambda instead of js function
Use d.resolve instead of js's resolve
Use d.reject instead of js's reject
You can resolve/reject with any type of paramters, and need not care about the troublesome of <> in c++ template.
While then is proposed, you can implement your own infix then via the named operator technique.
Create a struct then_t {}; and a static then_t then;. Now override operator* on the left and right so that std::future<bool> *then* lambda creates a std::async that waits on the future, and passes the result to the lambda, then returns the return value of the lambda.
This requires lots of care and attention, as you have to carefully create copies to avoid dangling references, and mess around with r and l value syntax to make it fully efficient.
The end syntax you get is:
aut fut = asyncLoader("cat.jpg");
fut *then* [&](Image img) { std::cout << "Image loaded: " << img; };
which is pretty close to what you want.
If you are really smart, you could even have it also support:
aut fut = asyncLoader("cat.jpg");
fut *then* [=] { std::cout << "Image loaded: " << fut.get(); };
which gets rid of some of the boilerplate and would be useful sometimes. This requires asyncLoader to return a std::shared_future instead of a future.
You could pass an object thats for example implementing a Runnable class to the "then" method of the Future class. Once the Future finished its work, call the "run" method of the passed object.
Take a look at https://github.com/Naios/continuable . It supports Javascript style .then(). It also supports exceptions with .fail() (instead of .catch()). There is a great talk about it here https://www.youtube.com/watch?v=l6-spMA_x6g
Use JavaScript-like Promises for C++20. It relies on C++20 coroutines, supports ES6 await/async semantics, and very importantly, it supports 'move' so you can write wrappers for frameworks like asio (e.g. because asio::ip::tcp::socket cannot be copied).
Link: https://github.com/virgil382/JSLikePromise
The question is a bit old, but here is a Javascript-like promise library (consist of a single header that you simply need to include) that aims to do exactly what you ask for, of course together with some sort of async I/O library to implement the actual asyncImageLoader().
https://github.com/alxvasilev/cpp-promise
Related
The thing is that I would like to create a global instance which I would be able to use separately by each coroutine to keep there, for instance, the list of named scopes, e.g. for log purposes.
so that when boost::asio::spawn is called a new custom state would be attached to the newly run coroutine.
As a guess, as a workaround it could be done by means of a global std::unordered_map indexed by smth similar to std::this_thread::get_id() but for coroutines. Yet right now I'm not aware of anything like that.
While it would be perfect if it is possible to accomplish this by a custom asio::yield_context. It keeps cancellation_slot, executor, why it cannot keep extra state? I have tryed to dig into the boost sources of yield_context, but I'm rather lost there, that's why I would appreciate some insights on this matter.
You need to implement await_transform for a custom type. That allows you to communicate with your promise type. Of course, that's an implementation detail of the library, so you haven't seen it yet.
Here's the await_transform for this_coro::executor_t:
// This await transformation obtains the associated executor of the thread of
// execution.
auto await_transform(this_coro::executor_t) noexcept
{
struct result
{
awaitable_frame_base* this_;
bool await_ready() const noexcept
{
return true;
}
void await_suspend(coroutine_handle<void>) noexcept
{
}
auto await_resume() const noexcept
{
return this_->attached_thread_->get_executor();
}
};
return result{this};
}
You can create your own awaitable type with your own promise-type, which adds you custom state.
There's a non-trivial amount of code here, that will be daunting to write. (It is to me). You should probably dive in with a simpler coroutine tutorial (as "simple" as that can be, which is not very).
I've seen a number of good talks
Gor Nishanov's from 2016 which I've personally watched and played along with, so I know it will do a good job https://www.youtube.com/watch?v=8C8NnE1Dg4A
A much more recent one by Andreas Fertig from 2022 https://www.youtube.com/watch?v=8sEe-4tig_A (which I haven't seen)
The same event had Andreas Weis "Deciphering C++ Coroutines - A Diagrammatic Coroutine Cheat Sheet" (which can also be found elsewhere as "Deciphering C++ Coroutines - A Visual Approach")
There is this blog post series by Raymond Chen which seems very apt. In particular this installment should land you close to the mark: C++ coroutines: Snooping in on the coroutine body
I am building a system where a top layer communicates with a driver layer, who in turn communicate with a I2C layer. I have put my I2C driver behind a message queue, in order to make it thread safe and serialize access to the I2C bus.
In order to return the reply to the driver, the I2C layer returns a std::future with a byte buffer inside that is filled out when the I2C bus read actually happens.
All this works and I like it.
My problem is that I also want the driver to return a future to the top layer, however this future will then depend on the previous future (when the I2C driver future-returns a byte buffer, the driver will have to interpret and condition those bytes to get the higher-level answer), and I am having problems making this dependency "nice".
For example, I have a driver for a PCT2075 temperature sensor chip, and I would like to have a:
future<double> getTemperature()
method in that driver, but so far I can't think of a better way than to make an intermediate "future-holder" class and then return that:
class PCT2075
{
public:
class TemperatureFuture
{
private:
std::future<std::pair<std::vector<uint8_t>, bool>> temperatureData;
public:
TemperatureFuture(std::future<std::pair<std::vector<uint8_t>, bool>> f);
template< class Clock, class Duration >
std::future_status wait_until(const std::chrono::time_point<Clock, Duration>& timeout_time) const;
void wait() const; // wait and wait_until just waits on the internal future
double get();
};
TemperatureFuture getTemperature();
};
This structure works and I can go forward with it, but for some reason I am not super happy with it (though I can't quite explain why... :/ ).
So my questions are:
Is there some pattern that can make this better?
Would it make sense to let TemperatureFuture inherit directly from std::future (I have heard that "do not inherit from std classes" is a good rule)?
Or is this just how you do it, and I should stop worrying about nothing?
Ps. I also have another method whose answer relies on two I2C reads, and thus two different futures. It is possible to rework this to only have a one-on-one dependency, but the current way can handle the one-on-multiple variant so it would be nice if a potential new proposal also could.
You are looking for an operation called then, which as commenters note is sadly missing even in C++20.
However, it's not hard to write a then yourself.
template<typename Fun, typename... Ins>
std::invoke_result_t<Fun, Ins...> invoke_future(Fun fun, std::future<Ins>... futs) {
return fun(futs.get()...);
}
template<typename Fun, typename... Ins>
std::future<std::invoke_result_t<Fun, Ins...>> then(Fun&& fun, std::future<Ins>... futs) {
return std::async(std::launch::deferred, invoke_future<Fun, Ins...>, std::forward<Fun>(fun), std::move(futs)...);
}
I expect something like this wasn't standardised because it makes loads of assumptions about how the function should be run once the result is ready.
A future that just reinterprets the results of a previous future or gathers multiple futures is a good job for std::async(std::launch::deferred, ...). This doesn't launch any thread, it executes on request.
std::future<int> f1 = std::async([]() -> int { return 1; });
std::future<float> f2 = std::async(
std::launch::deferred,
[](std::future<int>&& f) -> float { return f.get(); },
std::move(f1));
std::printf("%f\n", f2.get());
The downside is that certain features will not work, e.g. wait_until.
If, instead, you need to launch a new asynchronous action once the first future is ready (e.g. send another I2C message, or compute the higher-level result in a thread pool), C++ does not offer any better solution than making this part of your original task. For example your I2C driver could accept a list of std::functions as callbacks.
I am stuck at C++ 98
I have written a basic event system in C++, similar to how things are done in scripting languages.
Events/callbacks are stored in a map
std::hash_map<uint32_t, std::vector<EVENTHANDLER> >
API example
ES es;
es.On("MyEvent", MyCallback);
Event event(1,2,3);
es.Emit("MyEvent", event);
es.Off("MyEvent", MyCallback);
I want to implement the typical One method, where after the callback is executed, it is then removed so that it only ever fires once. In JS this is easy, you can wrap the callback in an anonymous function
one(event, cb){
this.on(event, (e) => {
cb(e);
this.off(event, cb);
});
}
But I cannot use lambda in C++ 98. Is there any other trivial way to do this? I thought maybe if a callback registers with "one" it can be put into a vector of "one" callbacks that must be iterated each time an event is emitted, but that is a backup solution.
There doesn't seem to be any reason your ES can't do this.
Add the capability to call es.Once("MyEvent", MyCallback);
Have this and es.On set a boolean flag inside wherever you're storing these things, bool once
After running a task, if task.once, just do Off(TheEventImRunning, TheCallbackItUses).
So it's the logic you proposed, but without using a lambda. Just write it normally in your functions, with a boolean stored somewhere to decide whether or not the extra logic needs to be run.
Alternatively, you could consider binding MyCallback to some wrapper that additionally does the Off() call. If MyCallback is just a function pointer or a std::function then this is probably quite easy. But we cannot give concrete examples without knowing more about your code.
So, I see the usefulness of lambda functions when they are used to replace functors, but when would you want to use them in an object oriented programming (with classes) setting in general and why?
Okay, so a little more (and less) helpful response than my comment.
Closures (that is, functions declared inside other functions, which capture the outer function's variables) are an interesting back-channel way to implement classes. Watch:
auto MakeCounter(int initialCount)
{
int currentCount = initialCount;
struct {
std::function<void()> increment = [&]() { currentCount++; };
std::function<int()> getCount = [&]() { return currentCount; };
} theCounter;
return theCounter;
}
Now theCounter is a structure with two members, one which increments the count and the other which retrieves the current count. Notice that the struct doesn't itself need to store the current count; that is instead implicitly held by the two lambdas, which share currentCount between them.
There's a few problems with this.
It doesn't compile. Not even mostly. There are a ton of things wrong with that code snippet. Actually, it crashes GCC 4.9. Whee!
Even if it did compile, it wouldn't work properly, because C++ closures aren't very powerful -- they can't keep captured variables alive after the end of their scopes. Only a language with actual GC could do this.
C++ already has classes, so why bother?
Nevertheless, you see this sort of pattern in other languages which either support (proper) closures and GC but don't have native facilities for classes (e.g. some variants of LISP), or do support classes but so crappily that it's arguably better to do things this way (e.g. Matlab).
So in C++ they're just for replacing functor boilerplate. They don't offer any additional power. In some other languages, they're rather more versatile, and more widely important.
After some research on internet for an efficient way to implement events in C++, I found the following methods
Interface class - Applications can override the virtual functions in the derived class
Normal Callback mechanism using function pointers
Delegates using Boost.function
Signals and slots (as used in Qt)
I am confused on advantages and disadvantages of each of these and when to use anyone of this.
Which is the best method and why?
Is there any other solutions which are better than the ones listed?
FWIW, my vote would be for Boost Signals any day.
Boost ensures portability. Of course it integrates nicely with e.g. Boost Asio, Functional, Bind, etc.
Update:
Signals2
This documentation describes a thread-safe variant of the original Boost.Signals library. There have been some changes to the interface to support thread-safety, mostly with respect to automatic connection management. [....]
Boost ensures portability. Of course it integrates nicely with e.g. Boost Asio, Functional, Bind, etc.
boost::signals2::signal sig;
sig.connect(&print_sum);
sig.connect(&print_product);
sig.connect(&print_difference);
sig.connect(&print_quotient);
sig(5., 3.);
This program will print out the following:
The sum is 8
The product is 15
The difference is 2
The quotient is 1.66667
sample actions:
void print_sum(float x, float y)
{
std::cout << "The sum is " << x+y << std::endl;
}
void print_product(float x, float y)
{
std::cout << "The product is " << x*y << std::endl;
}
void print_difference(float x, float y)
{
std::cout << "The difference is " << x-y << std::endl;
}
void print_quotient(float x, float y)
{
std::cout << "The quotient is " << x/y << std::endl;
}
Have you checked GBL library? It has all facilities that you might need (and probably more) for even-driven design. You can build (real) timed and un-timed models with it. It's pure C++, not polluted with macros. It also makes use of C++0x for improved performance. Also if you use C++0x compiler you get lambda functions working as event handlers -- it's very powerful. GBL supports synchronous and asynchronous event handlers, threads, and fibers. It abstracts event flow via signals and ports. With some ingenuity and careful design you can use asynchronous event handlers and significantly improve performance on multicore/multiprocessor systems. It also has a graphical designer and tracer.
Building and maintaining event-driven applications can be very difficult without visualization, designer helps with that a lot. Debugging event-driven applications can also be very difficult, because you no longer have a sequential execution, rather the execution is jumping from one event handler to another, so having an event tracer helps significantly.
First two options are part of the basic C++ standard, with the function callbacks being compatible with C code as well.
The other two options require using boost and Qt respectively.
Advantages/disadvantages is kindof too broad a question, and the answer depends greatly on what you're doing, in what environment and for what purpose.
You can use Observer design pattern. Here is an example C++ source of it.
http://sourcemaking.com/design_patterns/observer/cpp/3