Boost logo

Boost :

From: Chris Richards (chris.richards_at_[hidden])
Date: 2006-11-08 12:44:34


>
> 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 <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
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.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk