Is thread pool using asio and thread_group working as intended?
Hello, 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? /Jonas
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.
participants (2)
-
Andrew Holden
-
Jonas Nilsson