
Comments inline. On Fri, Jun 17, 2011 at 01:33:02PM +0200, Alessandro Candini wrote:
On 17/06/11 12:39, Lars Viklund wrote:
---8<--- asio::io_service io; scoped_ptrasio::io_service::work work(new asio::io_service::work(io));
An io_service acts as the hub and dispatcher of completion handlers, typically used for network communication but can also be used for invoking functions on any thread that services the io_service. The 'work' object is needed to pretend that there are pending operations that the io_service is not aware of. If an io_service is out of work, it returns from the run() functions, which we do not want to do until we're done.
boost::thread_group tg; auto N = boost::thread::hardware_concurrency();
A thread_group is part of Boost.Thread and lets you create and join groups of threads. hardware_concurrency() simply counts the number of physical processors you have, so it's a good guess to base the number of worker threads on.
for (unsigned i = 0; i< N; ++i) tg.create_thread(boost::bind(&asio::io_service::run, boost::ref(io));
io_service::run() blocks until the service is out of work, and can be run in as many threads as you want. There's also single-shot variants and polling variants of it.
io.post(some_task); io.post(some_other_task);
io_service::post() takes something callable with the signature `void ()' and invokes it eventually on any thread that is servicing the io_service and isn't busy.
// invoke io.post whenever you want to enqueue something.
// time passes, shutdown time has arrived
work.reset(); tg.join_all(); ---8<---
When we're out of pending handlers, and have destroyed the last work item, the functions will start to return, and we can join all the threads.
Could you please give me a working example as little as possible, to better understand all this stuff?
io.post([when_done, other_data] { auto result = compute(other_data); when_done(result); }); This is the form most of my tasks have in the applications where I have a similar setup. You post a task that when completed informs whoever cares via a callback. As Jeroen mentioned on IRC, which I forgot to mention in my first message, this assumes that tasks are largely independent. If they're not and you have more concurrent tasks than there's workers, you might end up with blocking everything, as a handler runs to completion before returning control to run(). Normally, that's not horribly limiting, as the things you tend to block on tend to be asynchronous operations that Asio provides, like reading/writing to sockets, waiting on timers, etc. I recommend that you read the Asio docs, particularly the prose and background bits, and take a look at the examples. Michael Caisse's Boostcon presentation on an Asio Flash XML Server is quite enlightening as well. -- Lars Viklund | zao@acc.umu.se