A, good, thread pool keeps a set number of threads running and waiting to do something. The pool could be designed to scale up with the amount of work you need to do but I prefer specifying a fixed number of threads. A good way to choose this number is to use the number of cores/processors on the system + 1.
Some pools are fixed size so no more threads will be added. Other thread-pools are "cached" thread pools so it will reuse a free thread or will create a new one if none are available.
shutdownNow() should be used to shutdown the thread pool to gracefully exiting the application.
Thread pools do not make sense when you need thread which perform entirely dissimilar and unrelated actions, which cannot be considered "jobs"; e.g., One thread for GUI event handling, another for backend processing. Thread pools also don't make sense when processing forms a pipeline.
I think it is still not accepted into Boost, but a good staring point: threadpool. Some example of usage, from the web site:
#include "threadpool.hpp"
using namespace boost::threadpool;
// Some example tasks
void first_task()
{
...
}
void second_task()
{
...
}
void third_task()
{
...
}
void execute_with_threadpool()
{
// Create a thread pool.
pool tp(2);
// Add some tasks to the pool.
tp.schedule(&first_task);
tp.schedule(&second_task);
tp.schedule(&third_task);
// Leave this function and wait until all tasks are finished.
}
The argument "2" to the pool indicates the number of threads. In this case, the destruction of tp
waits for all threads to finish.
You might want to look at http://threadpool.sourceforge.net/
It is not hard to implement thread pool yourself using Boost.Thread. Depending on the task, you might want to use lock-free container for the queue instead of one from Standard Template Library. For example, fifo
container from lock free
library.
Good luck!
I've written a small example here. Basically what you need to do is to implement this piece of code:
asio::io_service io_service;
boost::thread_group threads;
auto_ptr<asio::io_service::work> work(new asio::io_service::work(io_service));
// Spawn enough worker threads
int cores_number = boost::thread::hardware_concurrency();
for (std::size_t i = 0; i < cores_number; ++i){
threads.create_thread(boost::bind(&asio::io_service::run, &io_service));
}
// Post the tasks to the io_service
for(vector<string>::iterator it=tasks.begin();it!=tasks.end();it++){
io_service.dispatch(/* YOUR operator()() here */);
}
work.reset();
I believe you can emulate a thread pool with an io_service in boost::asio. You can control the number of threads available to the io_service pool, and then you can "post" tasks to the io_service, which will get executed by one of the threads in the pool. Each such task has to be a functor (I believe).
I can't put an example here right now, but the asio documentation on io_service pools will outline how this can be done.
Here is a simple header-only task queue using a thread pool (built on Boost): taskqueue.hpp
The TaskQueue project page includes a sample application demonstrating how to use it:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With