mr-edd.co.uk :: horsing around with the C++ programming language

async

async allows you to call any C++ function or functor asynchronously. You are given a future object which may be queried for the return value or exception generated by the function.

Recent activity

Code

Clone the repository using mercurial:

> hg clone http://bitbucket.org/edd/async

Or get a zip file of the code.

Quick start

Suppose we have a long-running function which counts the number of primes up to the given limit. For large values of max:

std::size_t count_primes_upto(std::size_t max);

This function may take a long time. We can use async to do useful work while this calculation is performed:

#include <async/call.hpp>

async::layered_cage<async::catch_all> invoker; // this is an object that handles exceptions

// call count_primes_upto(987654321) asynchronously
async::future<std::size_t> fut = async::call(invoker, count_primes_upto, 987654321); 

// do something else in the mean time
// ...

std::size_t n = fut.value();

async supports the passing of arguments and receipt of return values by-reference using async::ref:

using async::ref;

// Load plugins in to the given vector and return a reference to the default
const plugin &load_plugins(const std::string &location, const std::vector<plugin> &plugins);

async::future<const plugin &> fut = 
    async::call(invoker, ref(load_plugins), "plugins", ref(plugins));

Further reading

I made a series of blog posts on the implementation details. Their a little out of date by now, but still generally relevant:

Comments

Anders Dalvander

[07/10/2007 at 09:33:00]

Are you planning to submit the async library to boost?

Edd

[07/10/2007 at 15:58:00]

Hi Anders!

The thought has crossed my mind. There are a couple of existing future-like mechanisms already in boost, as far as I understand it. So I'd have to look in to the possibility of reconciling the differences there.

Would you like to see something like this in boost? I guess I could see if there's any interest on the boost users mailing list...

Si

[16/12/2007 at 21:01:00]

Does the async library support callbacks? I’d like to make an object which calls an async operation and gets a callback when the function completes, rather than futures… Thanks

Edd

[17/12/2007 at 20:25:00]

Hi Si,

By callback, you mean that you would like a function/functor to get called when the asynchronous task completes? That's certainly possible, but what thread should the callback run in?

If it should run in the same thread as the asynchronous call, then perhaps the functor should be passed as an argument to async::call?

i.e.

void do_stuff(int x, int y, int z, const function &callback)
{
    // ...
    callback();
}

future<void> fut = async::call(cage, &do_stuff, x, y, z, my_callback);

If you google for "Qt concurrent future", you'll find the QFuture class from Qt. This allows you to connect a "slot" to a signal that is fired when a future completes. However, I believe that this relies on the existence of an event loop, which you may not have. And of course you have to use the whole Qt meta-compliation system, which I for one don't particularly like. It also has other problems, such as not being able to handle exceptions gracefully.

Nick

[21/04/2008 at 22:22:00]

Hello,

Thanks for working on this library. It looks like it has potential, however, I've hit a snag trying to use it with my code. You say that by default the call() function only supports calling functions with 5 arguments and to increase this, set the preprocessor directive ASYNC_MAX_CALL_ARGS to the maximum number of arguments you need to use. One of my functions has 21 arguments. I can increase ASYNC_MAX_CALL_ARGS up to 10 and that compiles fine, however, if I go over that, I get some compilation errors like:

/usr/include/boost/preprocessor/iteration/detail/local.hpp:67: error: wrong number of template arguments (11, should be 10)
/usr/include/boost/tuple/detail/tuple_basic.hpp:75: error: provided for ‘template class boost::tuples::tuple’
/usr/include/boost/preprocessor/iteration/detail/local.hpp:67: error: invalid type in declaration before ‘;’ token
/usr/include/boost/preprocessor/iteration/detail/local.hpp:67: error: no matching function for call to ‘get(const int&)’
/usr/include/boost/preprocessor/iteration/detail/local.hpp:67: error: no matching function for call to ‘get(const int&)’
/usr/include/boost/preprocessor/iteration/detail/local.hpp:67: error: no matching function for call to ‘get(const int&)’
/usr/include/boost/preprocessor/iteration/detail/local.hpp:67: error: no matching function for call to ‘get(const int&)’
/usr/include/boost/preprocessor/iteration/detail/local.hpp:67: error: no matching function for call to ‘get(const int&)’
/usr/include/boost/preprocessor/iteration/detail/local.hpp:67: error: no matching function for call to ‘get(const int&)’
/usr/include/boost/preprocessor/iteration/detail/local.hpp:67: error: no matching function for call to ‘get(const int&)’
/usr/include/boost/preprocessor/iteration/detail/local.hpp:67: error: no matching function for call to ‘get(const int&)’
/usr/include/boost/preprocessor/iteration/detail/local.hpp:67: error: no matching function for call to ‘get(const int&)’
/usr/include/boost/preprocessor/iteration/detail/local.hpp:67: error: no matching function for call to ‘get(const int&)’
/usr/include/boost/preprocessor/iteration/detail/local.hpp:67: error: no matching function for call to ‘get(const int&)’

It looks like boost's tuple library might have a problem with more than 10? Do you have any suggestions? Thanks,

Nick

Edd

[21/04/2008 at 23:46:00]

Hi Nick,

Unfortunately, it looks like boost::tuple can only support 10 template arguments. So I can only suggest that you group together related arguments in to classes.

Failing that, I’d have to write something similar to boost::tuple that supports more arguments. 21 seems somewhat excessive. Why do you need so many?

Edd

Nick

[22/04/2008 at 03:12:00]

Hi Edd,

Thanks... for a couple particular functions it just makes sense that they have that many arguments and I was hoping that I could just drop in this async library to see how it works but it looks like I’ll have to rewrite the functions a little to accommodate it. Thanks,

Nick

Vicente

[23/02/2009 at 20:29:00]

Hello,

I was looking for your Coco library in order to include it on the Boost wiki page of Libraries Under Construction (https://svn.boost.org/trac/boost/wiki/LibrariesUnderConstruction) when I saw your async library.
I’m developing a similar library Boost.InterThreads for Boost submission. I will really appreciate your comments on my library (https://svn.boost.org/trac/boost/wiki/LibrariesUnderConstruction?version=43#Boost.AsynchronousExecutors), mainly on the asynchronous executor/asynchronous completion token framework.

BTW, I have added both libraries (async and coco) on the wiki page. Let me know if you want I remove them from this wiki.

Vicente

Nick

[06/07/2009 at 23:25:00]

Edd,

I have used async for a couple projects and I really like how easy it makes doing threading with Boost. I’m wondering, are you planning on updating the code to work with newer versions of Boost? I recently tried upgrading Boost to 1.35.0 and am getting some compilation errors with async. Thanks,

Nick

Edd

[08/07/2009 at 00:09:00]

Hi Nick,

I haven’t touched the library for a while, but I just uploaded it to bitbucket. There’s a bug tracker here, so if you could post details of the problems you’re having I’ll see if I can find a little bit of time to devote to fixing them.

Patches are also welcome ;) But I agree that it would be nice for it to work with more recent version of boost, so I’ll see what I can do.

I’m moving to a new apartment right now, so it might be a little while until I get round to it. Then again, I don’t anticipate that it will be particularly hard to fix, so we’ll see.

Edd

Nick

[23/11/2009 at 23:17:00]

Edd

[24/11/2009 at 20:27:00]

Hi Nick.

Thanks very much for the diff. I'll apply it soon and probably give the library some much needed love, in general. My "spare time programming" of late has been devoted to re-doing this website (so it doesn't chew up comments, for example!), so I will get around to fixing async after that.

(optional)
(optional)
(required, hint)

Links can be added like [this one -> http://www.mr-edd.co.uk], to my homepage.
Phrases and blocks of code can be enclosed in {{{triple braces}}}.
Any HTML markup will be escaped.