捕获信号:使用成员函数作为信号处理程序

wal*_*mat 8 c++ linux signals

我有一个在无限循环中做一些工作的对象.该main()实例化对象,并调用该run()方法.由于我不想使用线程,我需要一个解决方案来使我的对象停止运行.下面你看看我想出了什么.

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;
    }

};
Run Code Online (Sandbox Code Playgroud)

如您所见,我需要异步发送信号.因此,我使用信号处理程序和sigaction.下面main我可以想象使用.

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();

}
Run Code Online (Sandbox Code Playgroud)

我现在期望的是:程序一直运行直到我发送SIGTERM被捕获并且将导致我的对象停止迭代并返回到main.

我现在有两个问题:

(a)在代码中,您看到标有"Compiler complains"的行,消息就像

boost::function<void(int)> cannot be converted to __sighandler_t {aka void (*)(int)}
Run Code Online (Sandbox Code Playgroud)

为了使这项工作,我需要改变什么?我认为f就像void f(int)信号处理程序在一些例子中得到的函数一样.

(b)对于那些想知道"那个人在做什么?"的人:你有什么建议如何更好地解决这类问题?

BЈо*_*вић 8

  • 为了使这项工作,我需要改变什么?我认为f就像void f(int),就像信号处理程序在一些例子中得到的函数一样.

编译器抱怨类型,因此您需要传递函数指针,而不是类型的对象boost::function<void(int)>.创建此类型的全局变量,并添加一个调用此对象的函数将起作用:

boost::function<void(int)> myCb;
void CallCb( int value )
{
  myCb(value);
}

int main(int argc, char** argv)
{
    Foo foo;
    struct sigaction sigIntHandler;

    myCb = std::bind1st(
      std::mem_fun(&Foo::catch_signal), &foo);
    f(5);  // this call works

    sigIntHandler.sa_handler = CallCb;
    sigemptyset(&sigIntHandler.sa_mask);
    sigIntHandler.sa_flags = 0;
    sigaction(SIGTERM, &sigIntHandler, NULL);
    s.run();

}
Run Code Online (Sandbox Code Playgroud)
  • 你对如何更好地解决这类问题有什么建议吗?

并不是的.这个想法没问题.我只想改变c ++ 11 lambda