Boost logo

Boost Users :

Subject: Re: [Boost-users] Is thread pool using asio and thread_group working asintended?
From: Andrew Holden (aholden_at_[hidden])
Date: 2012-04-13 14:05:55


On Thursday, April 12, 2012 11:17 AM, Jonas Nilsson wrote:

> I have found several sites illustrating the use of
> boost:asio::io_service together with boost::thread_group
> to create a simple thread pool system. I put together my
> own minimum example to test it:
>
> asio::io_service io_service;
> asio::io_service::work work(io_service);
> boost::thread_group threads;
> for (std::size_t i = 0; i < running_threads; ++i)
> {
> threads.create_thread(boost::bind(&asio::io_service::run,
&io_service));
> }
> for (int u = 0; u < work_units; u++)
> {
> io_service.post(boost::bind(WorkFunc, u));
> }
> io_service.stop();
> threads.join_all();
>
> When running the code, I find that all worker threads are
> killed when the following line is executed: io_service.stop();.
> Does the code work as intended? My impression from the comments
> to the examples I have seen is that it does not work as
> intended on my system.
>
> If the code does work as intended, is there a simple non polling
> method to determine when all work units are completed?

Yes, calling io_service.stop should end all threads as you described.

If you wish to let it finish everything before quitting, then destroy
the work object declared on the second line of your program. Maybe
restructure it like this:

asio::io_service io_service;
boost::thread_group threads;
{
    asio::io_service::work work(io_service);
    for (std::size_t i = 0; i < running_threads; ++i)
    {
        threads.create_thread(boost::bind(&asio::io_service::run,
&io_service));
    }
    for (int u = 0; u < work_units; u++)
    {
        io_service.post(boost::bind(WorkFunc, u));
    }
}
threads.join_all();

The idea is that the run functions will return as soon as all work is
finished. Work means all functions posted to the io_service, async
operations, and open io_service::work objects.

Since your sample only has the posted copies of WorkFunc and the work
object, letting the io_service::work object fall out of scope
essentially tells the io_service that you're not planning to give it any
more work and it can quit when it finishes what it does have.

I should point out that destroying the io_service::work object doesn't
mean you can't post any more functions. If you make your WorkFunc post
additional functions, then the threads will continue to run until all of
the newly posted functions return too.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net