asio & variable number of worker threads

I have implemented a simple tcp server using asio. I wish to be able to dynamically add and remove threads from the io_service thread pool, so that when the server is heavily loaded it can be given more threads to cope with the load, but when the load reduces it can release the threads back to the OS. I've tried posting to the io_service a handler which just throws an exception so that the thread exits, but it also resets the tcp connection and causes the acceptor thread to exit as well. Is there a way of cleanly stopping just a single io_service::run method which would then cause the thread to exit?

Just catch the exception and exit the thread gracefully. On 11/8/06, Chris Richards <chris.richards@yellowfeather.co.uk> wrote:
I have implemented a simple tcp server using asio. I wish to be able to dynamically add and remove threads from the io_service thread pool, so that when the server is heavily loaded it can be given more threads to cope with the load, but when the load reduces it can release the threads back to the OS.
I've tried posting to the io_service a handler which just throws an exception so that the thread exits, but it also resets the tcp connection and causes the acceptor thread to exit as well.
Is there a way of cleanly stopping just a single io_service::run method which would then cause the thread to exit? _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
-- Felipe Magno de Almeida

Even though the exception is caught it causes both the socket thread and the acceptor thread to exit. For example, if I have 2 threads running, with both boost::asio::ip::tcp::acceptor::async_accept and boost::asio::ip::tcp::socket::async_read_some operations outstanding, then if I call StopThread in the code shown below I would expect only one thread to exit. void IoServiceRunner::ThreadFn() { try { ioService_.run(); } catch (StopThreadException& ex) { std::cout << "StopThreadException occurred" << std::endl; } catch (std::exception& ex) { std::cout << "Exception occurred" << ex.what() << std::endl; } catch (...) { std::cout << "Unknown exception occurred"); } } void IoServiceRunner::StopThread() { ioService_.post(boost::bind(&IoServiceRunner::NullThreadFn, this)); } void IoServiceRunner::NullThreadFn() { throw StopThreadException(); } From: Felipe Magno de Almeida Sent: Wed 08/11/2006 16:13 To: boost@lists.boost.org Subject: Re: [boost] asio & variable number of worker threads Just catch the exception and exit the thread gracefully. On 11/8/06, Chris Richards <chris.richards@yellowfeather.co.uk> wrote:
I have implemented a simple tcp server using asio. I wish to be able to dynamically add and remove threads from the io_service thread pool, so that when the server is heavily loaded it can be given more threads to cope with the load, but when the load reduces it can release the threads back to the OS.
I've tried posting to the io_service a handler which just throws an exception so that the thread exits, but it also resets the tcp connection and causes the acceptor thread to exit as well.
Is there a way of cleanly stopping just a single io_service::run method which would then cause the thread to exit? _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
-- Felipe Magno de Almeida _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Even though the exception is caught it causes both the socket thread and the
acceptor thread to exit.
For example, if I have 2 threads running, with both
boost::asio::ip::tcp::socket::async_read_some operations outstanding, then if I call StopThread in the code shown below I would expect only one thread to exit.
void IoServiceRunner::ThreadFn() { try { ioService_.run(); } catch (StopThreadException& ex) { std::cout << "StopThreadException occurred" << std::endl; } catch (std::exception& ex) { std::cout << "Exception occurred" << ex.what() << std::endl; } catch (...) { std::cout << "Unknown exception occurred"); } }
void IoServiceRunner::StopThread() { ioService_.post(boost::bind(&IoServiceRunner::NullThreadFn, this)); }
void IoServiceRunner::NullThreadFn() { throw StopThreadException(); }
From: Felipe Magno de Almeida Sent: Wed 08/11/2006 16:13 To: boost <at> lists.boost.org Subject: Re: [boost] asio & variable number of worker threads
Just catch the exception and exit the thread gracefully.
On 11/8/06, Chris Richards <chris.richards <at> yellowfeather.co.uk> wrote:
I have implemented a simple tcp server using asio. I wish to be able to dynamically add and remove threads from the io_service thread pool, so that when the server is heavily loaded it can be given more threads to cope with the load, but when the load reduces it can release the threads back to the OS.
I've tried posting to the io_service a handler which just throws an exception so that the thread exits, but it also resets the tcp connection and causes
boost::asio::ip::tcp::acceptor::async_accept and the
acceptor thread to exit as well.
Is there a way of cleanly stopping just a single io_service::run method which would then cause the thread to exit? _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Sorry, that example is not quite right. At startup, an async_accept operation is started, and io_service::run is called on a single thread. Whenever a connection is accepted an async_read_some operation is started and another thread is created, upto a predefined maximum number of threads. The async_operation is also restarted. So the number of threads is equal to 1 + the number of connections, limited to a maximum number. As connections are disconnected I would like to be able to reduce the number of threads accordingly, so that if there are no active connections there will be just a single thread for the async_accept. I have coded this so that when a connection is disconnected, a check is made to see if the number of active connections has dropped below the number of running threads, if so then a call to StopThread shown in the code below is used in an attempt to stop one of the threads. What happens is that the expection is caught in one thread, and that thread exits gracefully, but also the handler for the async_accpet is called with an error stating "The I/O operation has been aborted because of either a thread exit or an application request.", causing that thread to exit as well. I think that by throwing an exception the socket is being reset somehow which causes the accept to complete as well. BTW: This is targeted for Linux but I'm testing on Windows.
participants (2)
-
Chris Richards
-
Felipe Magno de Almeida