Abfangen von Signalen: Verwenden Sie eine Member-Funktion als Signalhandler
Ich habe ein Objekt, das in einer Endlosschleife arbeitet. Dasmain()
instanziiert das Objekt und ruft das aufrun()
Methode. Da ich keine Threads verwenden möchte, benötige ich eine Lösung, damit mein Objekt nicht mehr ausgeführt wird. Unten sehen Sie, was ich mir ausgedacht habe.
struct Foo
{
void run()
{
running = 1;
while (running)
do_something_useful();
std::cout << "Execution stopped." << std::endl;
}
bool running;
void catch_signal(int signal)
{
std::cout << "Caught signal " << signal << std::endl;
if( signal == SIGTERM )
running = false;
}
};
Wie Sie sehen, muss ich asynchron ein Signal senden. Deshalb benutze ich einen Signalhandler undsigaction
. Unter demmain
Ich kann mir vorstellen, es zu benutzen.
int main(int argc, char** argv)
{
Foo foo;
struct sigaction sigIntHandler;
boost::function< void (int) > f;
f = std::bind1st(
std::mem_fun(&Foo::catch_signal), &foo);
f(5); // this call works
sigIntHandler.sa_handler = f; // compiler complains, "cannot assign ..."
sigemptyset(&sigIntHandler.sa_mask);
sigIntHandler.sa_flags = 0;
sigaction(SIGTERM, &sigIntHandler, NULL);
s.run();
}
Was ich jetzt erwarten würde: Das Programm läuft bis ich sendeSIGTERM
Das wird abgefangen und bewirkt, dass mein Objekt die Iteration stoppt und zum Hauptmenü zurückkehrt.
Ich habe jetzt zwei Fragen:
(a) In dem Code, den Sie in einer mit "Compiler complains" markierten Zeile sehen, sieht die Meldung so aus
boost::function<void(int)> cannot be converted to __sighandler_t {aka void (*)(int)}
Was muss ich ändern, damit dies funktioniert? Meiner Ansicht nachf
ist wievoid f(int)
Wie die Funktionen, die der Signalhandler in einigen Beispielen erhält.
(b) Für diejenigen unter Ihnen, die sich fragen: "Was macht dieser Typ?": Haben Sie einen Rat, wie Sie solche Probleme besser lösen können?