Captura de sinais: Use uma função de membro como manipulador de sinal
Eu tenho um objeto que faz algum trabalho em um loop infinito. omain()
instancia o objeto e chama orun()
método. Como não quero usar encadeamentos, preciso de uma solução para que meu objeto pare de ser executado. Abaixo você vê o que eu inventei.
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;
}
};
Como você vê, preciso enviar um sinal de forma assíncrona. Portanto, eu uso um manipulador de sinal esigaction
. Abaixo demain
Eu posso imaginar usar.
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();
}
O que eu esperaria agora: o programa funciona até eu enviarSIGTERM
que é capturado e fará com que meu objeto pare a iteração e retorne ao main.
Eu tenho duas perguntas agora:
(a) No código você vê uma linha marcada com "Compiler reclama", a mensagem é como
boost::function<void(int)> cannot be converted to __sighandler_t {aka void (*)(int)}
O que preciso mudar para que isso funcione? eu acho quef
é comovoid f(int)
, como as funções que o manipulador de sinais obtém em alguns exemplos.
(b) Para aqueles de vocês que se perguntam "o que esse cara está fazendo?": Você tem algum conselho sobre como resolver esse tipo de coisa melhor?