每种信号的含义
在Linux操作系统中,信号是一种进程间通信的方式,用于通知进程发生了某种事件。Linux中的普通信号(standard signals)有31个,每个信号都有特定的用途。以下是这31个普通信号的列表及其描述:
- SIGHUP (1): 挂起信号,通常在终端断开或关闭时发送给控制进程。
- SIGINT (2): 中断信号,通常由用户按下
Ctrl+C
键发送。 - SIGQUIT (3): 退出信号,通常由用户按下
Ctrl+\
键发送并生成核心转储。 - SIGILL (4): 非法指令,程序执行了非法或未定义的机器语言指令。
- SIGTRAP (5): 跟踪/断点陷阱,用于调试。
- SIGABRT (6): 异常终止,由
abort()
函数调用发送。 - SIGBUS (7): 总线错误,内存访问对齐错误。
- SIGFPE (8): 浮点异常,如除零或溢出。
- SIGKILL (9): 强制终止信号,不能被捕获或忽略,立即终止进程。
- SIGUSR1 (10): 用户定义信号1,应用程序可以自定义使用。
- SIGSEGV (11): 段错误,非法内存访问。
- SIGUSR2 (12): 用户定义信号2,应用程序可以自定义使用。
- SIGPIPE (13): 管道破裂,写入一个没有读取端的管道。
- SIGALRM (14): 闹钟信号,由
alarm()
函数设置的定时器到期时发送。 - SIGTERM (15): 终止信号,程序可以捕获该信号并执行清理操作。
- SIGSTKFLT (16): 协处理器堆栈错误(较少使用)。
- SIGCHLD (17): 子进程状态改变,当子进程终止或停止时发送给父进程。
- SIGCONT (18): 继续执行,如果进程已停止则恢复其执行。
- SIGSTOP (19): 停止执行,不能被捕获或忽略。
- SIGTSTP (20): 终端停止信号,通常由用户按下
Ctrl+Z
键发送。 - SIGTTIN (21): 后台进程尝试从终端读取时发送。
- SIGTTOU (22): 后台进程尝试向终端写入时发送。
- SIGURG (23): 紧急条件,套接字上有紧急数据可读。
- SIGXCPU (24): CPU时间限制超时。
- SIGXFSZ (25): 文件大小限制超时。
- SIGVTALRM (26): 虚拟定时器到期。
- SIGPROF (27): 统计定时器到期。
- SIGWINCH (28): 终端窗口大小改变。
- SIGPOLL (29): I/O操作事件(SysV定义)。
- SIGPWR (30): 电源故障。
- SIGSYS (31): 非法系统调用。
这些信号在编程和系统管理中有着重要的应用。通过使用信号,进程可以处理各种异常和特殊情况,实现更健壮和灵活的程序设计。
捕获SIGINT信号
SIGINT信号通常由用户按下Ctrl+C
键发送。以下代码展示了如何捕获和处理SIGINT信号:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>// 信号处理函数
void handle_sigint(int sig) {printf("Caught signal %d (SIGINT)\n", sig);
}int main() {// 注册信号处理函数signal(SIGINT, handle_sigint);// 无限循环,等待信号while (1) {printf("Running...\n");sleep(1);}return 0;
}
编译并运行该程序后,当你按下Ctrl+C
时,它将捕获SIGINT信号并调用handle_sigint
函数。
捕获SIGTERM信号
SIGTERM信号通常用于请求进程终止。以下代码展示了如何捕获和处理SIGTERM信号:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>// 信号处理函数
void handle_sigterm(int sig) {printf("Caught signal %d (SIGTERM)\n", sig);// 进行清理工作printf("Cleaning up...\n");// 终止程序_exit(0);
}int main() {// 注册信号处理函数signal(SIGTERM, handle_sigterm);// 无限循环,等待信号while (1) {printf("Running...\n");sleep(1);}return 0;
}
编译并运行该程序后,可以通过以下命令发送SIGTERM信号:
kill -SIGTERM <pid>
其中,<pid>
是程序的进程ID。
捕获SIGCHLD信号
SIGCHLD信号在子进程终止或停止时发送给父进程。以下代码展示了如何捕获和处理SIGCHLD信号:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <sys/wait.h>// 信号处理函数
void handle_sigchld(int sig) {// 等待子进程终止wait(NULL);printf("Caught signal %d (SIGCHLD). Child process terminated.\n", sig);
}int main() {// 注册信号处理函数signal(SIGCHLD, handle_sigchld);// 创建子进程pid_t pid = fork();if (pid == 0) {// 子进程代码printf("Child process running...\n");sleep(2);printf("Child process exiting...\n");_exit(0);} else {// 父进程代码printf("Parent process waiting for child to terminate...\n");// 无限循环,等待信号while (1) {sleep(1);}}return 0;
}
编译并运行该程序后,子进程将在2秒后终止,父进程将捕获SIGCHLD信号并调用handle_sigchld
函数。
两种不能被忽略的信号
SIGKILL和SIGSTOP
两种不能被捕捉的信号
SIGKILL和SIGSTOP