【问题标题】:SIGINT signal()/sigaction in C++C++ 中的 SIGINT 信号()/sigaction
【发布时间】:2011-09-30 13:43:03
【问题描述】:

这是我的代码:

void sigHandle(int sig)
{
    signal(SIGINT, sigHandle);    //Is this line necessairy?
    cout<<"Signal: "<<sig<<endl;    
}

int main(){

    signal(SIGINT, sigHandle);

    while(true){ //Supposed to loop until user exits.

    //rest of my code
    
    }
}

现在我对 signal() 的理解是,当收到 SIGINT 命令(Ctrl+C 对吗?)时,我的函数 sigHandle 应该用整数值调用2(SIGINT 编号),该方法应该运行并且程序应该退出。

我想做的只是打印信号编号并继续前进,但是在打印出“信号:2”后它会退出。

(最终我应该处理前 32 个中断,但我认为 Ctrl+C 将是最困难的,所以我从这里开始。)

在 main 中,如果我执行 signal(SIGINT, SIG_IGN); 它会正确忽略信号并且不会退出,但我现在无法知道我是否收到了 SIGINT 中断。

早些时候我在玩 sigaction 结构,但我找不到任何关于它的真正全面的文档,所以我决定只使用“原始”信号处理。

这是我的 sigaction 代码(与上面相同的问题):

struct sigaction action;
action.sa_handler = sigHandle;
sigemptyset(&action.sa_mask);
action.sa_flags = 0;
sigaction(SIGINT, &action, 0);

感谢您的帮助!

编辑

好的,所以在浏览手册页和互联网很多小时后,我遇到了一个(非常)贫民窟解决方案,涉及保存堆栈预无限循环,然后当中断来临时,做我需要做的事情,然后将堆栈重新设置回原来的位置并调用 sigrelse() 命令重新设置任何可能已更改但未重新加载的状态。

我知道这不是解决这个问题的最优雅/最有效/甚至不是社会可接受的解决方案,但它确实有效,据我所知,我没有在任何地方泄漏任何内存,所以一切都很好......

我仍在寻找解决此问题的方法,并且我认为我的堆栈重新设置恶作剧只是一种临时修复...

谢谢!

【问题讨论】:

  • signal(2) 已弃用,您应该使用sigaction(2)。请咨询您当地的man page

标签: c++ signals sigint


【解决方案1】:

还请注意,您不应在信号处理程序中调用 stdio(或其他不可重入函数)。 (您的信号处理程序可能会在 malloc 或它的 C++ 等价物的中间调用)

【讨论】:

    【解决方案2】:

    事实并非如此。您只需用相同的功能替换 SIGINT 的句柄。你的程序是如何执行等待的?

    如果你有类似的东西:

    int main
    { 
     // ...
    
      int r = read(fd, &buff, read_size); // your program hangs here, waiting for the data.
                                          // but if signal occurred during this period of time
                                          // read will return immediately, and r may != read_size
    
      return 0;  // then it will go straight to return.
    }
    

    【讨论】:

    • 我在某处读到,在某些 unix 环境中,signal() 命令在每次调用后都会重新设置为默认值。但是我知道那条线不是我的问题的原因,因为我后来添加了它,希望它能解决我的问题。
    • 信号中断系统调用,read 将立即返回。这可能是您的程序退出的原因。 linux.die.net/man/2/read - "...或者因为 read() 被信号中断..."
    • 即使在 sigHandle 中没有任何内容,程序仍然会退出,这是不应该的。 (对吧?)
    • 是的。它退出不是因为处理程序内部有东西,而是因为信号发生了。我编辑了我的帖子。
    • 啊,好的。我明白。我从用户那里得到的所有输入都发生在一个 while(true) 循环中。因此,使用您的示例,如果您将 read 命令卡在 while(true) 循环中,即使 read 在信号后立即返回,它不应该只是循环回来并再次挂起吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多