2017-08-14 3 views
0

Ich möchte einen Signalhandler zu meinem boost io_service hinzufügen, damit die Anwendung sauber heruntergefahren werden kann, wenn der Benutzer Strg-C drückt. Das ist natürlich leicht durch Anhalten der Schleife, so etwas getan:Boost asio-Handler, der den io_service nicht laufen lässt

boost::asio::io_service service; 
boost::asio::signal_set signals{ service, SIGINT, SIGTERM }; 

signals.async_wait(std::bind(&boost::asio::io_service::stop, &service)); 

Dadurch wird die Schleife normal hält, so dass die Destruktoren ihre Routine clean-up Verhalten zu tun.

Das Problem ist, sobald die Anwendung keine Arbeit mehr hat, hört es nicht auf, weil der Signalhandler noch einen Handler registriert hat und somit der io_service nie aufhört zu laufen.

Ich habe keinen sauberen Weg gefunden. Ich könnte natürlich die Signalverarbeitung selbst durchführen und dann einfach die Schleife stoppen, aber diese Art von Idee vereitelt die Idee, Boost (Portabilität) zu verwenden.

+0

Warum kann die Anwendung rufe 'signals.cancel()' auf, wenn es keine Arbeit mehr hat? – kenba

+0

Weil die Anwendung nicht weiß, wenn es keine Arbeit mehr hat. Der einzige, der weiß, ob mehr Arbeit zur Verfügung steht, ist der io_service. –

+0

Verwenden Sie 'io_service' als Thread-Pool? Was machst du genau? –

Antwort

0

Im folgenden Code hat http_server eine "hörende Buchse", um mehrere Verbindungen zu akzeptieren. Der Abhörsockel läuft ständig async_accept, so dass die io_service nie zu Ende geht. Die http_server.shutdown() Funktion schließt die Abhörsocket und alle offenen Verbindungen, so dass die io_service keine Arbeit mehr hat und nicht mehr läuft:

void handle_stop(ASIO_ERROR_CODE const&, // error, 
       int, // signal_number, 
       http_server_type& http_server) 
{ 
    std::cout << "Shutting down" << std::endl; 
    http_server.shutdown(); 
} 

... 

ASIO::io_service io_service; 
http_server_type http_server(io_service); 

... 


// The signal set is used to register termination notifications 
ASIO::signal_set signals_(io_service); 
signals_.add(SIGINT); 
signals_.add(SIGTERM); 
#if defined(SIGQUIT) 
signals_.add(SIGQUIT); 
#endif // #if defined(SIGQUIT) 

// register the handle_stop callback 
signals_.async_wait([&http_server] 
    (ASIO_ERROR_CODE const& error, int signal_number) 
{ handle_stop(error, signal_number, http_server); }); 

... 

io_service.run(); 
std::cout << "io_service.run complete, shutdown successful" << std::endl; 

Diese Methode wird auch für Thread-Pools funktioniert, siehe: thread_pool_http_server.cpp

Verwandte Themen