簡體   English   中英

捕獲信號:使用成員函數作為信號處理程序

[英]Catching signals: Use a member function as signal handler

我有一個在無限循環中做一些工作的對象。 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;
    }

};

如您所見,我需要異步發送信號。 因此,我使用信號處理程序和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();

}

我現在期望的是:程序一直運行,直到我發送被捕獲的SIGTERM並且將導致我的對象停止迭代並返回到main。

我現在有兩個問題:

(a)在代碼中,您看到標有“Compiler complains”的行,消息就像

boost::function<void(int)> cannot be converted to __sighandler_t {aka void (*)(int)}

為了使這項工作,我需要改變什么? 我認為f就像void f(int) ,就像信號處理程序在一些例子中得到的函數一樣。

(b)對於那些想知道“那個人在做什么?”的人:你有什么建議如何更好地解決這類問題?

  • 為了使這項工作,我需要改變什么? 我認為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();

}
  • 你對如何更好地解決這類問題有什么建議嗎?

並不是的。 這個想法沒問題。 我只想改變c ++ 11 lambda

您可以在信號處理程序中輕松地進行操作。 基本上,您可以將值存儲在類型為sig_atomic_t的對象中。 例如,插入cout不一定有效。 如果你有C ++ 11,你可以使用原子類型或顯式圍欄做更多的事情,但是對標准庫的任何其他調用都不需要做任何合理的事情。

所以,盡管如此,你可以做的是編寫一個函數(自由函數或靜態成員函數)(但這里有一個微妙的問題,C ++鏈接:正式的靜態成員函數不起作用,但在實踐中它始終會))調用成員函數,而成員函數又將running設置為false (假設您已將running類型更改為sig_atomic_t )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM