i using html server 3 example boost learning tool (http://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/examples.html#boost_asio.examples.http_server_3) asynchronous message handling.
i have taken example, , turned library server object can instantiate in programs. thing have done above example remove main.cpp , compile library. , works extend can instantiate server object in code, , pass messages command line.
where struggling how terminate server gracefully. sample code see this:
server::server(const std::string& address, const std::string& port, std::size_t thread_pool_size, handler &handler) : thread_pool_size_(thread_pool_size), signals_(io_service_), acceptor_(io_service_), new_connection_(), request_handler_(handler) { // register handle signals indicate when server should exit. // safe register same signal multiple times in program, // provided registration specified signal made through asio. signals_.add(sigint); signals_.add(sigterm); signals_.async_wait(boost::bind(&server::handle_stop, this));
so asynchronous thread set listen signals , respond them
i have implemented server object in thread in program follows:
class serverworker { public: serverworker(std::string thehost, std::string theport) { host = thehost; port = theport; } void start() { try { myrequesthandler handler; int ncores = boost::thread::hardware_concurrency(); server *mserver = new server(host, port, ncores, handler); svr->run(); } catch(std::exception &e) { /* */ } } void stop() { mserver->stop(); // should raise signal , send server // don't know how } private: std::string host; std::string port; server *mserver; }; test(bsgt_lbsserver_stress, bsgt_singleton) { // launch server on new thread serverworker sw(bsgt_default_ipaddress, bsgt_default_port_str); boost::function<void()> th_func = boost::bind(&serverworker::start, &sw); boost::thread swthread = boost::thread(th_func); // // how signal server in swthread stop? }
how implement stop() method on server object send signal itself? have tried:
1) raise(sigterm) - kills whole program
2) raise(sigint) - kills whole program
raise()
appropriate having process signal itself.
void serverworker::stop() { std::raise(sigterm); }
be aware raise()
asynchronous. issue signal , return immediately. hence, control may continue before io_service
processes enqueued signalhandler.
void run_server() { // launch server on new thread serverworker server_worker(...); boost::thread worker_thread([&server_worker]() { server_worker.start(); }); ... // raises sigterm. may return before io_service stopped. server_worker.stop(); // need synchronize worker_thread. `worker_thread` may still // in `serverworker::start()` go out of scope. additionally, // `worker_thread` joinable, destructor may invoke // `std::terminate()`. }
here minimal example demonstrating using boost.asio signal handling, raise()
, , synchronization:
#include <cassert> #include <csignal> #include <iostream> #include <thread> #include <boost/asio.hpp> int main() { boost::asio::io_service io_service; // prevent io_service running out of work. boost::asio::io_service::work work(io_service); // boost.asio register internal handler sigterm. boost::asio::signal_set signal_set(io_service, sigterm); signal_set.async_wait( [&io_service]( const boost::system::error_code& error, int signal_number) { std::cout << "got signal " << signal_number << "; " "stopping io_service." << std::endl; io_service.stop(); }); // raise sigterm. std::raise(sigterm); // time raise() returns, boost.asio has handled sigterm // own internal handler, queuing internally. @ point, boost.asio // ready dispatch notification user signal handler // (i.e. provided signal_set.async_wait()) within // io_service event loop. std::cout << "io_service stopped? " << io_service.stopped() << std::endl; assert(false == io_service.stopped()); // initiate thread run io_service. invoke // queued handler ready completion. std::thread work_thread([&io_service]() { io_service.run(); }); // synchornize on work_thread. letting run completion. work_thread.join(); // io_service has been explicitly stopped in async_wait // handler. std::cout << "io_service stopped? " << io_service.stopped() << std::endl; assert(true == io_service.stopped()); }
output:
io_service stopped? 0 got signal 15; stopping io_service. io_service stopped? 1
Comments
Post a Comment