Łapanie sygnałów: użyj funkcji członka jako obsługi sygnału
Mam obiekt, który działa w nieskończonej pętli. Themain()
tworzy instancję obiektu i wywołujerun()
metoda. Ponieważ nie chcę używać wątków, potrzebuję rozwiązania, aby mój obiekt przestał działać. Poniżej zobaczysz, co wymyśliłem.
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;
}
};
Jak widzisz, muszę wysłać sygnał asynchronicznie. Dlatego używam obsługi sygnału isigaction
. Poniżejmain
Mogę sobie wyobrazić, żeby użyć.
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();
}
Czego oczekiwałbym teraz: program działa do momentu wysłaniaSIGTERM
który zostanie złapany i spowoduje, że mój obiekt zatrzyma iterację i powróci do głównego.
Mam teraz dwa pytania:
(a) W kodzie widocznym jest linia oznaczona „Kompilator skarży się”, wiadomość jest podobna
boost::function<void(int)> cannot be converted to __sighandler_t {aka void (*)(int)}
Co muszę zmienić, aby to działało? Myślęf
jest jakvoid f(int)
, podobnie jak funkcje obsługiwane przez program obsługi sygnałów w niektórych przykładach.
(b) Dla tych, którzy zastanawiają się „co robi ten facet?”: Czy masz jakieś rady, jak lepiej rozwiązać ten problem?