Reputation: 9818
I am currently posting handlers to my io_service and execute them in a thread pool.
io_serv.post( boost::bind(&Class::bar, p1, p2) );
My workers run this function:
m_mutex.lock();
std::cout << "[" << boost::this_thread::get_id()
<< "] Thread Start" << std::endl;
m_mutex.unlock();
size_t tasks = m_serv.run();
m_mutex.lock();
std::cout << "[" << boost::this_thread::get_id() << "] accomplished "
<< tasks << " tasks" << std::endl;
m_mutex.unlock();
So far so good but now I want to trigger an event when the handler queue is empty without killing my active (but waiting) threads.
Is it possible and how ?
Upvotes: 3
Views: 4362
Reputation: 7357
First time i see using of asio as a queue dispatcher. Not bad technique i think.
Well, i suggest you are running io_service::run to serve the handlers. As documentation says, run will block until io_service is stopped OR all work has finished. So you can run your "empty queue event" after io_service::run:
while( !finished ) {
io_serv.run();
io_serv.reset();
io_serv.post( boost::bind(&Class::fill_queue, instance) );
}
This in case you have no other asio activity on this io_service and you not using io_service::work.
As mentioned in comments you using io_service::work so plan A failed(it will not work since this class prevents exitting on empty queue). Well, you can do io_serv.post()
after each bunch of io_serv.post()
-s for thread jobs. The handler can contain waiting with boost::condition while other threads finish their work. As you do post()
for this after actual jobs, i think asio will call it after dispatching all jobs, but its subject for investigation. Anyway that handler can re-post()
himself to free current thread if condition is not ready yet.
But i think easiest way is to replace io_service::work with equialent while construct.
Upvotes: 3