linux C下截获Ctrl+C键盘事件或其它异常事件

单纯的做一下记录笔记

“C/C++” 当在LInux下运行程序时,一般main函数都是使用while循环等待的,如果想退出或结束程序时,只能按Ctrl+C来结束这个进程,但这意味着某些连接是异常断开的,导致服务端无端的一直收到异常信息,所以为了解决程序异常退出问题,捕捉Ctrl+C异常事件,然后在释放使用的东西,让程序正常退出,所以这里就需要用到signal函数

使用平台LInux:
1、signal详解
 #include <signal.h>

 typedef void (*sighandler_t)(int);

 sighandler_t signal(int signum, sighandler_t handler);


2、Linux下signal信号汇总
SIGHUP       1          /* Hangup (POSIX).  */                          终止进程     终端线路挂断
SIGINT       2          /* Interrupt (ANSI).  */                        终止进程     中断进程 Ctrl+C
SIGQUIT      3          /* Quit (POSIX).  */                            建立CORE文件终止进程,并且生成core文件 Ctrl+\
SIGILL       4          /* Illegal instruction (ANSI).  */              建立CORE文件,非法指令
SIGTRAP      5          /* Trace trap (POSIX).  */                      建立CORE文件,跟踪自陷
SIGABRT      6          /* Abort (ANSI).  */
SIGIOT       6          /* IOT trap (4.2 BSD).  */                      建立CORE文件,执行I/O自陷
SIGBUS       7          /* BUS error (4.2 BSD).  */                     建立CORE文件,总线错误
SIGFPE       8          /* Floating-point exception (ANSI).  */         建立CORE文件,浮点异常
SIGKILL      9          /* Kill, unblockable (POSIX).  */               终止进程     杀死进程
SIGUSR1      10         /* User-defined signal 1 (POSIX).  */           终止进程     用户定义信号1
SIGSEGV      11         /* Segmentation violation (ANSI).  */           建立CORE文件,段非法错误
SIGUSR2      12         /* User-defined signal 2 (POSIX).  */           终止进程     用户定义信号2
SIGPIPE      13         /* Broken pipe (POSIX).  */                     终止进程     向一个没有读进程的管道写数据
SIGALARM     14         /* Alarm clock (POSIX).  */                     终止进程     计时器到时
SIGTERM      15         /* Termination (ANSI).  */                      终止进程     软件终止信号
SIGSTKFLT    16         /* Stack fault.  */
SIGCLD       SIGCHLD    /* Same as SIGCHLD (System V).  */
SIGCHLD      17         /* Child status has changed (POSIX).  */        忽略信号     当子进程停止或退出时通知父进程
SIGCONT      18         /* Continue (POSIX).  */                        忽略信号     继续执行一个停止的进程
SIGSTOP      19         /* Stop, unblockable (POSIX).  */               停止进程     非终端来的停止信号
SIGTSTP      20         /* Keyboard stop (POSIX).  */                   停止进程     终端来的停止信号 Ctrl+Z
SIGTTIN      21         /* Background read from tty (POSIX).  */        停止进程     后台进程读终端
SIGTTOU      22         /* Background write to tty (POSIX).  */         停止进程     后台进程写终端
SIGURG       23         /* Urgent condition on socket (4.2 BSD).  */    忽略信号     I/O紧急信号
SIGXCPU      24         /* CPU limit exceeded (4.2 BSD).  */            终止进程     CPU时限超时
SIGXFSZ      25         /* File size limit exceeded (4.2 BSD).  */      终止进程     文件长度过长
SIGVTALRM    26         /* Virtual alarm clock (4.2 BSD).  */           终止进程     虚拟计时器到时
SIGPROF      27         /* Profiling alarm clock (4.2 BSD).  */         终止进程     统计分布图用计时器到时
SIGWINCH     28         /* Window size change (4.3 BSD, Sun).  */       忽略信号     窗口大小发生变化
SIGPOLL      SIGIO      /* Pollable event occurred (System V).  */
SIGIO        29         /* I/O now possible (4.2 BSD).  */              忽略信号     描述符上可以进行I/O
SIGPWR       30         /* Power failure restart (System V).  */
SIGSYS       31         /* Bad system call.  */
SIGUNUSED    31
3、Linux下signal信号表格
信号起源默认行为含义
SIGHUPPOSIXTerm控制终端挂起
SIGINTANSITerm键盘输入以终端进程(ctrl + C)
SIGQUITPOSIXCore键盘输入使进程退出(Ctrl + \)
SIGILLANSICore非法指令
SIGTRAPPOSIXCore断点陷阱,用于调试
SIGABRTANSICore进程调用abort函数时生成该信号
SIGIOT4.2BSDCore和SIGABRT相同
SIGBUS4.2BSDCore总线错误,错误内存访问
SIGFPEANSICore浮点异常
SIGKILLPOSIXTerm终止一个进程。该信号不可被捕获或被忽略
SIGUSR1POSIXTerm用户自定义信号之一
SIGSEGVANSICore非法内存段使用
SIGUSR2POSIXTerm用户自定义信号二
SIGPIPEPOSIXTerm往读端关闭的管道或socket链接中写数据
SIGALRMPOSIXTerm由alarm或settimer设置的实时闹钟超时引起
SIGTERMANSITerm终止进程。kill命令默认发生的信号就是SIGTERM
SIGSTKFLTLinuxTerm早期的Linux使用该信号来报告数学协处理器栈错误
SIGCLDSystem VIgn和SIGCHLD相同
SIGCHLDPOSIXIgn子进程状态发生变化(退出或暂停)
SIGCONTPOSIXCont启动被暂停的进程(Ctrl+Q)。如果目标进程未处于暂停状态,则信号被忽略
SIGSTOPPOSIXStop暂停进程(Ctrl+S)。该信号不可被捕捉或被忽略
SIGTSTPPOSIXStop挂起进程(Ctrl+Z)
SIGTTINPOSIXStop后台进程试图从终端读取输入
SIGTTOUPOSIXStop后台进程试图往终端输出内容
SIGURG4.3 BSDIgnsocket连接上接收到紧急数据
SIGXCPU4.2 BSDCore进程的CPU使用时间超过其软限制
SIGXFSZ4.2 BSDCore文件尺寸超过其软限制
SIGVTALRM4.2 BSDTerm与SIGALRM类似,不过它只统计本进程用户空间代码的运行时间
SIGPROF4.2 BSDTerm与SIGALRM 类似,它同时统计用户代码和内核的运行时间
SIGWINCH4.3 BSDIgn终端窗口大小发生变化
SIGPOLLSystem VTerm与SIGIO类似
SIGIO4.2 BSDTermIO就绪,比如socket上发生可读、可写事件。因为TCP服务器可触发SIGIO的条件很多,故而SIGIO无法在TCP服务器中用。SIGIO信号可用在UDP服务器中,但也很少见
SIGPWRSystem VTerm对于UPS的系统,当电池电量过低时,SIGPWR信号被触发
SIGSYSPOSIXCore非法系统调用
SIGUNUSEDCore保留,通常和SIGSYS效果相同
4.1、应用实例
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
using namespace std;

bool g_bExit = false;
void Ctrl_c(int)
{
	printf("Ctrl + c detected!\n");
	g_bExit = true;
}

int main(int argc, char* argv[]{
	signal(SIGINT,&Ctrl_c);
	//一直循环不让程序退出
	while(!g_bExit)
	{
		sleep(2);
	}
	//执行其他东西释放
}

4.2、网上找了一个例子
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
using namespace std;

void sig_handler(int signum)
{
    if(0 > signum)
    {
        fprintf(stderr,"sig_handler param err. [%d]\n",signum);
        return;
    }
    if(SIGINT == signum)
    {
        printf("Received signal [%s]\n",SIGINT==signum?"SIGINT":"Other");
    }
    if(SIGQUIT == signum)
    {
        printf("Received signal [%s]\n",SIGQUIT==signum?"SIGQUIT":"Other");
    }

    return;
}

int main(int argc,char **argv)
{
    printf("Wait for the signal to arrive.\n ");

    /*登记信息*/
    signal(SIGINT,sig_handler);
    signal(SIGQUIT,sig_handler);

    pause();
    pause();

    signal(SIGINT,SIG_IGN);
    return 0;
}

有两个信号可以停止进程:SIGTERM和SIGKILL。 SIGTERM 比较友好,进程能捕捉这个信号,根据您的需要来关闭程序。

在关闭程序之前,您可以结束打开的记录文件和完成正在做的任务。在某些情况下,假如进程正在进行作业而且不能中断,那么进程可以忽略这个SIGTERM信号。

对于 SIGKILL 信号,进程是不能忽略的。这是一个 “我不管您在做什么,立刻停止”的信号。假如您发送SIGKILL信号给进程,Linux就将进程停止在那里。

函数说明
sigaddset将信号signo 加入到信号集合之中;
sigdelset将信号从信号集合中删除;
sigemptyset函数初始化信号集合set,将set 设置为空;
sigfillset也初始化信号集合,只是将信号集合设置为所有信号的集合;

转载:http://blog.csdn.net/wangeen/article/details/8349243

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值