Ich schreibe ein Cross-Plattform-Server-Programm in C++ mit Boost.Asio. Nach dem HTTP-Server-Beispiel unter this page, möchte ich eine Benutzerbeendigungsanforderung behandeln, ohne implementierungsspezifische APIs zu verwenden. Ich habe ursprünglich versucht, die Standard-C-Signalbibliothek zu verwenden, konnte aber kein für Asio geeignetes Designmuster finden. Das Windows example's Design scheint der am nächsten gelegenen Signalbibliothek zu ähneln, aber es gibt eine Race-Bedingung, bei der der Console-Ctrl-Handler aufgerufen werden konnte, nachdem das Server-Objekt zerstört wurde. Ich versuche, undefiniertes Verhalten zu vermeiden, wie es der C++ Standard vorgibt.Standard Weg, um ein sauberes Herunterfahren mit Boost.Asio
Gibt es eine standardmäßige (und korrekte) Möglichkeit, den Server zu stoppen?
Probleme zu veranschaulichen mit der C-Signal-Bibliothek:
#include <csignal>
#include <functional>
#include <boost/asio.hpp>
using std::signal;
using boost::asio::io_service;
namespace
{
std::function<void()> sighandler;
}
extern "C"
{
static void handle_signal(int);
}
void handle_signal(int)
{
// error - undefined behavior
sighandler();
}
int main()
{
io_service s;
sighandler = std::bind(&io_service::stop, &s);
auto old_sigint = signal(SIGINT, &handle_signal);
if (old_sigint == SIG_IGN)
// race condition? raise SIGINT before I can set ignore back
signal(SIGINT, SIG_IGN);
auto old_sigterm = signal(SIGTERM, &handle_signal);
if (old_sigterm == SIG_IGN)
// race condition? raise SIGTERM before I can set ignore back
signal(SIGTERM, SIG_IGN);
s.run();
// reset signals so I can clear reference to io_service
if (old_sigterm != SIG_IGN)
signal(SIGTERM, SIG_DFL);
if (old_sigint != SIG_IGN)
signal(SIGINT, SIG_DFL);
// clear reference to io_service, but can I be sure that handle_signal
// isn't being executed?
sighandler = nullptr;
// io_service is destroyed
}
@Timothy fragen Sie, wie Sie einen Signal-Handler für ein Signal wie SIGINT installieren? Oder, was in diesem Signalhandler zu tun, um Ihren HTTP-Server herunterzufahren? –
@Sam hinzugefügt ein csignal Design-Beispiel – Timothy003
@Timothy Sie können 'io_service :: stop' aus Ihrem Signal-Handler nicht sicher aufrufen, selbst wenn es in eine' boost :: -Funktion eingepackt ist. Dies führt zu undefiniertem Verhalten. Sehen Sie [meine Antwort] (http://stackoverflow.com/questions/4639909/standard-way-to-perform-a-clean-shutdown-with-boost-asio/4639977#4639977) für eine Liste von Funktionen, die Sie können Aufruf von innerhalb eines Signalhandlers. –