信号处理错误

时间:2017-03-29 16:16:52

标签: c++ c++11 signal-handling

当我使用my_handler作为函数时,没有错误,但我不能,因为我必须在那里使用另一种方法。

如果我在下面构建代码:  错误:无效使用成员函数 on(你忘了'()'吗?)

这是我在C ++中的第一个程序

void Client::my_handler(int s){
    if (s == SIGINT){
        printf("SIGINT\n");
    // here I have to use stop_thread method 
    }
}


int main (int argc, const char **argv) {
  Client client(argc, argv);
  client.before_start();

  struct sigaction sigIntHandler;

  sigIntHandler.sa_handler = (__sighandler_t) client.my_handler; //error here
  sigemptyset(&sigIntHandler.sa_mask);
  sigIntHandler.sa_flags = 0;
  sigaction(SIGINT, &sigIntHandler, NULL);

  client.run();

  return 0;
}

2 个答案:

答案 0 :(得分:4)

在C ++中,成员函数(与类实例关联的函数,例如此处的client.my_handler)与常规函数(此处为int main(int arg, const char** argv))不同。这就是为什么你不能将client.my_handler投射到__sighandler_t

Client::my_handler有一个隐藏参数,Client*。所以,它的签名(从某个角度来看)看起来像void my_handler(Client* this, int s)。 C ++在幕后做了一些事情,这样你就可以引用this的变量,而不必this->(大多数时候)。当你做一些像打电话

的事情
client.my_handler(SIGINT)

C ++正在将其转换为

my_handler(&client, SIGINT)

现在你可以看到问题:__sighandler_t是函数指针的别名,但client.my_handler实际上是两个指针:{{1}的函数指针}和指向my_handler的指针。

信号处理程序只接受函数指针,而不是更通用的函数对象(函数指针加上其他一些数据)。信号处理来自C,但函数对象来自C ++。

信号处理程序的唯一解决方案是某种全局变量。

答案 1 :(得分:0)

@SJL提供了一个很好的解释,说明为什么这不起作用,并提供了一种C风格的解决方法。

如果你可以使用Boost,boost::asio::signal_set可以用来处理更多C ++风格的信号。 async_wait function可以接收lambda,绑定成员函数指针或具有适当签名的任何其他可调用类型。