信号
- [1. 信号 的产生与处理](#1. 信号 的产生与处理)
- [2. 信号 的分类](#2. 信号 的分类)
-
- [2.1 获取信号的描述信息 ---strsignal() / psignal()](#2.1 获取信号的描述信息 ---strsignal() / psignal())
- [3. 信号集---sigemptyset() / sigfillset() / sigaddset() / sigdelset() / sigismember()](#3. 信号集---sigemptyset() / sigfillset() / sigaddset() / sigdelset() / sigismember())
1. 的产生与处理
c#define SIGHUP 1 /* Hangup (POSIX). */ #define SIGINT 2 // 当用户在终端按下中断字符(通常是CTRL + C)时,内核将发送SIGINT信号给前台进程组中的每一个进程。该信号的系统默认操作是终止进程的运行。所以通常我们都会使用CTRL + C来终止一个占用前台的进程,原因在于大部分的进程会将该信号交给系统去处理,从而执行该信号的系统默认操作。 #define SIGQUIT 3 //当用户在终端按下退出字符(通常是CTRL + \)时,内核将发送SIGQUIT信号给前台进程组中的每一个进程。该信号的系统默认操作是终止进程的运行、并生成可用于调试的核心转储文件。进程如果陷入无限循环、或不再响应时,使用SIGQUIT信号就很合适。所以对于一个前台进程,既可以在终端按下中断字符CTRL + C、也可以按下退出字符CTRL + \来终止,当然前提条件是,此进程会将SIGINT信号或SIGQUIT信号交给系统处理(也就是没有将信号忽略或捕获),进入执行该信号所对应的系统默认操作。 #define SIGILL 4 //如果进程试图执行非法(即格式不正确)的机器语言指令,系统将向进程发送该信号。该信号的系统默认操作是终止进程的运行。 #define SIGTRAP 5 /* Trace trap (POSIX). */ #define SIGABRT 6 //当进程调用abort()系统调用时(进程异常终止),系统会向该进程发送SIGABRT信号。该信号的系统默认操作是终止进程、并生成核心转储文件。 #define SIGIOT 6 /* IOT trap (4.2 BSD). */ #define SIGBUS 7 //产生该信号(总线错误,bus error)表示发生了某种内存访问错误。该信号的系统默认操作是终止进程。 #define SIGFPE 8 //该信号因特定类型的算术错误而产生,譬如除以0。该信号的系统默认操作是终止进程。 #define SIGKILL 9 //此信号为"必杀(sure kill)"信号,用于杀死进程的终极办法,此信号无法被进程阻塞、忽略或者捕获,故而"一击必杀",总能终止进程。使用SIGINT信号和SIGQUIT信号虽然能终止进程,但是前提条件是该进程并没有忽略或捕获这些信号,如果使用SIGINT或SIGQUIT无法终止进程,那就使用"必杀信号"SIGKILL吧。 #define SIGUSR1 10 //该信号和SIGUSR2信号供程序员自定义使用,内核绝不会为进程产生这些信号,在我们的程序中,可以使用这些信号来互通通知事件的发生,或是进程彼此同步操作。该信号的系统默认操作是终止进程。 #define SIGSEGV 11 //这一信号非常常见,当应用程序对内存的引用无效时,操作系统就会向该应用程序发送该信号。引起对内存无效引用的原因很多,C语言中引发这些事件往往是解引用的指针里包含了错误地址(譬如,未初始化的指针),或者传递了一个无效参数供函数调用等。该信号的系统默认操作是终止进程。 #define SIGUSR2 12 //与SIGUSR1信号相同。 #define SIGPIPE 13 //涉及到管道和socket,当进程向已经关闭的管道、FIFO 或套接字写入信息时,那么系统将发送该信号给进程。该信号的系统默认操作是终止进程。 #define SIGALRM 14 //与系统调用alarm()或setitimer()有关,应用程序中可以调用alarm()或setitimer()函数来设置一个定时器,当定时器定时时间到,那么内核将会发送SIGALRM信号给该应用程序。该信号的系统默认操作是终止进程。 #define SIGTERM 15 //这是用于终止进程的标准信号,也是kill命令所发送的默认信号(kill xxx,xxx表示进程pid),有时我们会直接使用"kill -9 xxx"显式向进程发送SIGKILL信号来终止进程,然而这一做法通常是错误的,精心设计的应用程序应该会捕获SIGTERM信号、并为其绑定一个处理函数,当该进程收到SIGTERM信号时,会在处理函数中清除临时文件以及释放其它资源,再而退出程序。如果直接使用SIGKILL信号终止进程,从而跳过了SIGTERM信号的处理函数,通常SIGKILL终止进程是不友好的方式、是暴力的方式,这种方式应该作为最后手段,应首先尝试使用SIGTERM,实在不行再使用最后手段SIGKILL。 #define SIGSTKFLT 16 /* Stack fault. */ #define SIGCLD SIGCHLD //与SIGCHLD信号同义。 #define SIGCHLD 17 //当父进程的某一个子进程终止时,内核会向父进程发送该信号。当父进程的某一个子进程因收到信号而停止或恢复时,内核也可能向父进程发送该信号。注意这里说的停止并不是终止,你可以理解为暂停。该信号的系统默认操作是忽略此信号,如果父进程希望被告知其子进程的这种状态改变,则应捕获此信号。 #define SIGCONT 18 //将该信号发送给已停止的进程,进程将会恢复运行。当进程接收到此信号时并不处于停止状态,系统默认操作是忽略该信号,但如果进程处于停止状态,则系统默认操作是使该进程继续运行。 #define SIGSTOP 19 //这是一个"必停"信号,用于停止进程(注意停止不是终止,停止只是暂停运行、进程并没有终止),应用程序无法将该信号忽略或者捕获,故而总能停止进程。 #define SIGTSTP 20 //这也是一个停止信号,当用户在终端按下停止字符(通常是CTRL + Z),那么系统会将SIGTSTP信号发送给前台进程组中的每一个进程,使其停止运行。 #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时间超出对应的资源限制时,内核将发送此信号给该进程。 #define SIGXFSZ 25 /* File size limit exceeded (4.2 BSD). */ #define SIGVTALRM 26 //应用程序调用setitimer()函数设置一个虚拟定时器,当定时器定时时间到时,内核将会发送该信号给进程。 #define SIGPROF 27 /* Profiling alarm clock (4.2 BSD). */ #define SIGWINCH 28 //在窗口环境中,当终端窗口尺寸发生变化时(譬如用户手动调整了大小,应用程序调用ioctl()设置了大小等),系统会向前台进程组中的每一个进程发送该信号。 #define SIGPOLL SIGIO //同SIGIO一样 #define SIGIO 29 //用于提示一个异步IO事件的发生,譬如应用程序打开的文件描述符发生了I/O事件时,内核会向应用程序发送SIGIO信号。 #define SIGPWR 30 /* Power failure restart (System V). */ #define SIGSYS 31 //如果进程发起的系统调用有误,那么内核将发送该信号给对应的进程。 #define SIGUNUSED 31
2. 的分类
根据可靠性将信号分为, (1~31) 与 (34~64)
根据时间关系将信号分为,实时信号(等同于 ) 与 非实时信号(等同于 )
2.1 获取信号的描述信息 ---strsignal() / psignal()
c#include <string.h> #include <signal.h> char *strsignal(int sig); // C库,用于获取到参数sig指定的信号对应的描述信息,返回该描述信息字符串的指针 void psignal(int sig, const char *s); // C库,会将参数sig指定的信号对应的描述信息输出到标准错误,并且还允许调用者添加一些输出信息,由参数s指定
3. ---sigemptyset() / sigfillset() / sigaddset() / sigdelset() / sigismember()
c#include <signal.h> int sigemptyset(sigset_t *set); //系统调用,用于初始化信号集,使其不包含任何信号 int sigfillset(sigset_t *set); //系统调用,用于初始化信号集,使其包含所有信号(包括所有实时信号) int sigaddset(sigset_t *set, int signum); //系统调用,用于向信号集中添加一个信号 int sigdelset(sigset_t *set, int signum); //系统调用,用于向信号集中移除一个信号 int sigismember(const sigset_t *set, int signum); //系统调用,用于测试某一个信号是否在指定的信号集中
*[信号集]: 能表示多个信号(一组信号)的数据类型
*[信号]: 信号是事件发生时对进程的通知机制,也可以把它称为软件中断。信号与硬件中断的相似之处在于能够打断程序当前执行的正常流程,其实是在软件层次上对中断机制的一种模拟。大多数情况下,是无法预测信号达到的准确时间,所以,信号提供了一种处理异步事件的方法。
*[可靠信号]: 支持排队,不会丢失的信号
*[不可靠信号]: 指的是可能丢失的信号(信号值小于SIGRTMIN(34)的信号都是不可靠信号)





