Linux信号类型以及处理方式

1 信号类型

在Linux操作系统下,可以通过命令kill -l 来查看当前系统中存在的信号名称和编号:

信号的说明:

#define SIGHUP 1 /* Hangup (POSIX). 终端连接断开信号*/

#define SIGINT 2 /* Interrupt (ANSI). 中断信号,终端中输入ctrl+c,可中断前台进程*/

#define SIGQUIT 3 /* Quit (POSIX). 退出信号,终端中输入ctrl+\,可退出前台进程,同时产生core文件*/

#define SIGILL 4 /* Illegal instruction (ANSI). 非法指令信号,4.3BSD的abort函数产生该信号 */

#define SIGTRAP 5 /* Trace trap (POSIX). 调试信号,当在程序中设置断点后,该信号使得调试程序获得控制权*/

#define SIGABRT 6 /* Abort (ANSI). 程序异常终止信号,abort函数产生该信号 */

#define SIGIOT 6 /* IOT trap (4.2 BSD). 功能同SIGABRT*/

#define SIGBUS 7 /* BUS error (4.2 BSD). 程序访问不存在的内存区域时,产生该信号*/

#define SIGFPE 8 /* Floating-point exception (ANSI). 算术异常,如除以0*/

#define SIGKILL 9 /* Kill, unblockable (POSIX). 不能被忽略,非阻塞,可杀死任意一个运行中的进程*/

#define SIGUSR1 10 /* User-defined signal 1 (POSIX). 用户自定义1*/

#define SIGSEGV 11 /* Segmentation violation (ANSI). 当程序访问没有访问权限的内存区域,或者访问非可读的内存区域时,产生该信号,如数组越界 */

#define SIGUSR2 12 /* User-defined signal 2 (POSIX). 用户自定义2 */

#define SIGPIPE 13 /* Broken pipe (POSIX). 当管道读端已关闭,继续往管道中写,产生该信号 */

#define SIGALRM 14 /* Alarm clock (POSIX). alarm函数超时时产生该信号,默认动作是程序终止 */

#define SIGTERM 15 /* Termination (ANSI). 终止程序信号,命令kill默认使用该参数*/

#define SIGSTKFLT 16 /* Stack fault. */

#define SIGCLD SIGCHLD /* Same as SIGCHLD (System V). */

#define SIGCHLD 17 /* Child status has changed (POSIX). 子进程终止或停止时,产生该信号,默认被忽略*/

#define SIGCONT 18 /* Continue (POSIX). 继续*/

#define SIGSTOP 19 /* Stop, unblockable (POSIX). 不能被忽略,非阻塞,停止一个作业控制进程*/

#define SIGTSTP 20 /* Keyboard stop (POSIX). ctrl+z产生该信号,改信号使得前台进程挂起*/

#define SIGTTIN 21 /* Background read from tty (POSIX). */

#define SIGTTOU 22 /* Background write to tty (POSIX). */

#define SIGURG 23 /* Urgent condition on socket (4.2 BSD). */

#define SIGXCPU 24 /* CPU limit exceeded (4.2 BSD). 进程超过了CPU软限制产生该信号*/

#define SIGXFSZ 25 /* File size limit exceeded (4.2 BSD). 进程超过了文件大小软限制产生该信号*/

#define SIGVTALRM 26 /* Virtual alarm clock (4.2 BSD). */

#define SIGPROF 27 /* Profiling alarm clock (4.2 BSD). */

#define SIGWINCH 28 /* Window size change (4.3 BSD, Sun). */

#define SIGPOLL SIGIO /* Pollable event occurred (System V). */

#define SIGIO 29 /* I/O now possible (4.2 BSD). */

#define SIGPWR 30 /* Power failure restart (System V). */

#define SIGSYS 31 /* Bad system call. */

#define SIGUNUSED 31

#define _NSIG 65 /* Biggest signal number + 1 

(including real-time signals). */

#define SIGRTMIN (__libc_current_sigrtmin ()).实时信号的最小值 34

#define SIGRTMAX (__libc_current_sigrtmax ()).实时信号的最大值 65

2 信号处理

signal 的函数原型:

#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);

根据函数原型可以看出由两部分组成,一个是真实处理信号的函数,另一个是注册函数了。
对于函数sighandler_t signal(int signum, sighandler_t handler); 来说,signum 显然是信号的编号,handler 是中断函数的指针。
同样,typedef void (*sighandler_t)(int); 中断函数的原型中,有一个参数是 int 类型,显然也是信号产生的类型,方便使用一个函数来处理多个信号。以下是一个简单信号注册的代码示例。

#include <signal.h>
#include <stdio.h>
#include <unistd.h>
//typedef void (*sighandler_t)(int)
void handler(int signum)
{
    if(signum == SIGIO)
        printf("SIGIO   signal: %d\n", signum);
    else if(signum == SIGUSR1)
        printf("SIGUSR1   signal: %d\n", signum);
    else
        printf("error\n");
}

int main()
{
    //sighandler_t signal(int signum, sighandler_t handler);
    signal(SIGIO, handler);
    signal(SIGUSR1, handler);
    printf("%d  %d\n", SIGIO, SIGUSR1);
    while(1)
    {
        sleep(10);
    }
    return 0;
}

通过系统发出对应的信号,可以得出处理结果如下:

注意,SIGKILL(kill -9)以及SIGSTOP(kill -19)这两个信号是不能被忽略和非阻塞的,信号一旦发出必须终止当前PID对应的进程/线程,因此不能被捕获处理。

posted @ 2021-08-22 21:45  Jcpeng_std  阅读(373)  评论(0编辑  收藏  举报