Linux中的Ctrl + C中断事件处理

moz*_*ors 25 c c++ linux signals

我正在开发一个使用C++并使用Linux GNU C Compiler编译的应用程序.但是,我想调用一个函数,因为用户使用CtrlC 键来中断脚本.我该怎么办?任何答案将不胜感激.

Gri*_*han 55

按下时Ctr + C,操作系统会向进程发送信号.有很多信号,其中一个是SIGINT.SIGINT("程序中断")是终止信号之一.

还有更多种类的终止信号,但有关SIGINT的有趣之处在于它可以由您的程序处理(捕获).SIGINT的默认操作是程序终止.也就是说,如果您的程序没有专门处理此信号,则当您按下Ctr + C程序时终止作为默认操作.

要更改信号的默认操作,您必须注册要捕获的信号.要在C程序中注册信号(至少在POSIX系统下),有两个功能

  1. signal(int signum,sighandler_t handler);
  2. sigaction(int signum,const struct sigaction*act,struct sigaction*oldact); .

这些函数要求标头signal.h包含在您的C代码中.我在下面提供了一个简单的signal函数示例和注释.

#include <stdio.h>
#include <stdlib.h>
#include <signal.h> //  our new library 
volatile sig_atomic_t flag = 0;
void my_function(int sig){ // can be called asynchronously
  flag = 1; // set flag
}

int main(){
  // Register signals 
  signal(SIGINT, my_function); 
  //      ^          ^
  //  Which-Signal   |-- which user defined function registered
  while(1)  
    if(flag){ // my action when signal set it 1
        printf("\n Signal caught!\n");
        printf("\n default action it not termination!\n");
        flag = 0;
    }     
  return 0;
}  
Run Code Online (Sandbox Code Playgroud)

注意:您应该只在信号处理程序中调用安全/授权函数.例如,避免在信号处理程序中调用printf.

您可以使用gcc编译此代码并从shell执行它.代码中存在无限循环,它将一直运行,直到您SIGINT按下发送信号Ctr + C.

  • 你可以留意评论,我只是试着给你一个快速的起点.我相信通过更多努力,您将详细探索这些事情. (2认同)
  • 感谢您的回复和回答,这非常有效. (2认同)

Car*_*rum 11

键入CtrlC通常会导致shell发送SIGINT到您的程序.为该信号添加处理程序(通过signal(2)sigaction(2)),CtrlC按下时可以执行您喜欢的操作.

或者,如果您只关心在程序退出之前进行清理,那么设置退出处理程序atexit(3)可能更合适.

  • `atexit()` 不是替代方案,因为当程序由于信号而存在时,以这种方式注册的函数不会被调用。 (3认同)

phy*_*us9 5

您可以使用信号宏。

以下是如何处理它的示例:

#include <signal.h>
#include <stdio.h>
void sigint(int a)
{
    printf("^C caught\n");
}
int main()
{
    signal(SIGINT, sigint);
    for (;;) {}
}
Run Code Online (Sandbox Code Playgroud)

示例输出:

Ethans-MacBook-Pro:~ phyrrus9$ ./a.out
^C^C caught
^C^C caught
^C^C caught
^C^C caught
^C^C caught
Run Code Online (Sandbox Code Playgroud)

  • 避免在信号处理程序中使用 printf (10认同)