I have the following thread pool.
#include <queue>
#include <map>
#include <boost/shared_ptr.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/thread/thread.hpp>
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp> // remove me (only for io)
class ThreadPool
{
void run() {
// get some work from a task queue and then work on it
}
public:
void work_as_mainthread(void) { m_io_service.run(); }
ThreadPool(int poolSize = 4) : timer(m_io_service)
{
timer.expires_from_now(boost::posix_time::seconds(1));
m_pWork.reset( new boost::asio::io_service::work(m_io_service) );
for ( int i = 0; i < poolSize; ++i)
m_threadGroup.create_thread( boost::bind(&boost::asio::io_service::run, &m_io_service) );
}
private:
boost::asio::io_service m_io_service;
boost::asio::deadline_timer timer;
boost::shared_ptr<boost::asio::io_service::work> m_pWork;
boost::thread_group m_threadGroup;
};
int main()
{
int n_threads = 2;
ThreadPool pool(n_threads);
// add some tasks here...
pool.work_as_mainthread();
return 0;
}
It is a minimal exaple, full code here. Compile like this:
g++ -Wall -g -lboost_thread -lboost_date_time -lboost_system main.cpp -o main
Note that I have no async_wait() called (I don’t know why I should need it, the thread pool works so far).
Now, it might happen that suddenly one task wants another task to be done before the other task’s timeout. What’s the best way to tell the m_io_service to execute the handler immediatelly (even if the timer is not interested yet), and then to continue as if nothing happened? I could not figure out from the sparse documentation, really.
This did not work:
timer.expires_at(boost::posix_time::microsec_clock::universal_time());
Note that
expires_atonly setsdealine_timerexpiration time, but doesn’t “enable” the timer, so there’s no asynchronous operation associated with the timer. You should callasync_waitpassing it a completion handler: when the timeout is expired or the timer is cancelled, this handler gets called in one of the associatedio_service‘s threads.Calling
io_service::postis unrelated todeadline_timer. It just posts your functor toio_servicequeue, andio_serviceinvokes it as soon as it can in one of its threads.