Exception handling in Boost.Asio when io_service has thread

If the application has only one io_service object and is thread-safe (see the code below), what will happen if one of the async handlers throws an exception. How it spreads and, more importantly, the best way to deal with them.

 std::list< boost::shared_ptr< the_client > > clients_list; for(int i = 0; i < n_threads; i++) { clients_list.insert(boost::make_shared< the_client >( io_service, server_host, server_port )); } for(unsigned int i = 0; i < n_threads; i++) { threads.create_thread(boost::bind(&boost::asio::io_service::run, boost::ref(io_service))); } for(std::list< boost::shared_ptr< the_client > >::iterator itr = clients_list.begin(); itr != clients_list.end(); ++itr) { (*itr)->connect_to_server_and_run_statemachine(); } 

Here the_client::connect_to_server_and_run_statemachine() establishes a connection to the server and initiates asynchronous connection processing.

I know a question on a similar topic , but that doesn't take into account the multithreaded io_service script.

+4
source share
1 answer

Nothing magical happens. If you catch an exception somewhere, your catch handle it. Otherwise, an uncaught exception terminates the process.

How you should deal with this depends on what you want. If an exception should never happen, then let it stop the process. If you want to eat or handle exceptions, then write a function that wraps io_service::run in a try / catch and starts threads instead.

I do not like to put intelligence away from code. My preferred solution is that my asynchronous functions do not throw exceptions unless there is a really fatal error. If an asynchronous function knows how to handle an exception that it can throw, then it should catch it.

However, it is perfectly acceptable to wrap run if that makes sense in your application.

+3
source

Source: https://habr.com/ru/post/1444105/


All Articles