1. 信号的概念:
信号是用于进程间通信的一种机制,它是一种软件中断,用来通知进程发生了某个事件。当某个进程需要与另一个进程进行交互或者处理某些特殊情况时,可以发送一个信号给目标进程。
常见的信号类型包括:
- SIGHUP(挂起信号)
- SIGINT(中断信号)
- SIGQUIT(退出信号)
- SIGILL(非法指令信号)
- SIGABRT(异常终止信号)
- SIGFPE(浮点异常信号)
- SIGKILL(强制退出信号)
- SIGSEGV(段错误信号)
- SIGPIPE(管道破裂信号)
- SIGTERM(终止信号)
还有其他信号,共计约 64 种,每个信号都有一个唯一的编号和名称。
2. 64种信号量及其详细解释:
下面是64种信号量及其详细解释的Markdown表格:
信号编号 | 信号名称 | 说明 |
---|---|---|
1 | SIGHUP | 挂起信号。通常由终端断开或退出导致。 |
2 | SIGINT | 中断信号。通常由用户在终端上按下Ctrl+C触发。 |
3 | SIGQUIT | 退出信号。通常由用户在终端上按下Ctrl+\触发。 |
4 | SIGILL | 非法指令信号。当进程执行了一个非法指令时,操作系统会发送该信号给进程。 |
5 | SIGTRAP | 跟踪陷阱信号。当进程收到调试命令时,操作系统会发送该信号给进程。 |
6 | SIGABRT | 异常终止信号。由调用abort()函数产生,表示进程非正常终止。 |
7 | SIGBUS | 总线错误信号。当进程执行了一个内存访问错误时,操作系统会发送该信号给进程。 |
8 | SIGFPE | 浮点异常信号。当进程执行一个浮点运算错误时,会收到该信号。 |
9 | SIGKILL | 强制退出信号。无法被忽略、捕获或阻塞,用于立即终止进程。 |
10 | SIGUSR1 | 用户自定义信号1。用于在进程间自定义通信。 |
11 | SIGSEGV | 段错误信号。当进程访问了一个无效的内存地址或进行了无效的内存操作时,会收到该信号。 |
12 | SIGUSR2 | 用户自定义信号2。用于在进程间自定义通信。 |
13 | SIGPIPE | 管道破裂信号。当进程向一个已关闭的管道进行写操作时,会收到该信号。 |
14 | SIGALRM | 闹钟信号。通常由调用alarm()函数设置的定时器超时触发。 |
15 | SIGTERM | 终止信号。通常用于请求进程正常终止。 |
16 | SIGSTKFLT | 协处理器堆栈错误信号。当协处理器执行了一个堆栈错误指令或检测到堆栈错误时,操作系统会发送该信号给进程。 |
17 | SIGCHLD | 子进程状态改变信号。当一个进程的子进程停止或退出时,父进程会收到该信号。 |
18 | SIGCONT | 继续执行信号。用于恢复之前被暂停的进程的执行。 |
19 | SIGSTOP | 停止执行信号。无法被忽略、捕获或阻塞,用于暂停进程的执行。 |
20 | SIGTSTP | 终端停止信号。通常由用户在终端上按下Ctrl+Z触发,用于暂停前台进程的执行。 |
21 | SIGTTIN | 后台进程读写终端的信号。当一个后台进程尝试读取终端时,会收到该信号。 |
22 | SIGTTOU | 后台进程读写终端的信号。当一个后台进程尝试写入终端时,会收到该信号。 |
23 | SIGURG | 紧急数据信号。表示接收到了带外数据。 |
24 | SIGXCPU | CPU时间限制信号。当进程超过了预设的CPU时间限制时,会收到该信号。 |
25 | SIGXFSZ | 文件大小限制信号。当进程超过了预设的文件大小限制时,会收到该信号。 |
26 | SIGVTALRM | 虚拟定时器信号。通常由调用setitimer()函数设置的虚拟定时器超时触发。 |
27 | SIGPROF | 专用定时器信号。通常由调用setitimer()函数设置的专用定时器超时触发。 |
28 | SIGWINCH | 窗口大小改变信号。当终端窗口大小发生改变时,会收到该信号。 |
29 | SIGIO | 异步I/O信号。表示I/O操作可以进行。 |
30 | SIGPWR | 电源故障信号。当检测到系统电源故障时,会发送该信号。 |
31 | SIGSYS | 非法系统调用信号。当进程执行了一个非法的系统调用时,会收到该信号。 |
32 | SIGBABY | 进程变更信号。当一个进程成为另一个进程的子进程时,会收到该信号。 |
33 | SIGEMT | EMT指令信号。当进程执行了一个EMT指令时,会收到该信号。 |
34 | SIGSTKFLT | 协处理器堆栈错误信号。当协处理器执行了一个堆栈错误指令或检测到堆栈错误时,操作系统会发送该信号给进程。 |
35 | SIGIO | 异步I/O信号。表示I/O操作可以进行。 |
36 | SIGCLD | 旧式的子进程状态改变信号。与SIGCHLD相同。 |
37 | SIGPOLL | Pollable事件信号。与SIGIO相同。 |
38 | SIGSTOP | 停止执行信号。无法被忽略、捕获或阻塞,用于暂停进程的执行。 |
39 | SIGTSTP | 终端停止信号。通常由用户在终端上按下Ctrl+Z触发,用于暂停前台进程的执行。 |
40 | SIGCONT | 继续执行信号。用于恢复之前被暂停的进程的执行。 |
41 | SIGCHLD | 子进程状态改变信号。当一个进程的子进程停止或退出时,父进程会收到该信号。 |
42 | SIGTTIN | 后台进程读写终端的信号。当一个后台进程尝试读取终端时,会收到该信号。 |
43 | SIGTTOU | 后台进程读写终端的信号。当一个后台进程尝试写入终端时,会收到该信号。 |
44 | SIGIO | 异步I/O信号。表示I/O操作可以进行。 |
45 | SIGXCPU | CPU时间限制信号。当进程超过了预设的CPU时间限制时,会收到该信号。 |
46 | SIGXFSZ | 文件大小限制信号。当进程超过了预设的文件大小限制时,会收到该信号。 |
47 | SIGVTALRM | 虚拟定时器信号。通常由调用setitimer()函数设置的虚拟定时器超时触发。 |
48 | SIGPROF | 专用定时器信号。通常由调用setitimer()函数设置的专用定时器超时触发。 |
49 | SIGWINCH | 窗口大小改变信号。当终端窗口大小发生改变时,会收到该信号。 |
50 | SIGINFO | 信息请求信号。Symbolic常为SIGPWR,与SIGPWR相同。 |
51 | SIGUSR1 | 用户自定义信号1。用于在进程间自定义通信。 |
52 | SIGUSR2 | 用户自定义信号2。用于在进程间自定义通信。 |
53 | SIGTHR | Thread信号。用于线程的中断和终止。 |
54-59 | 保留 | |
60 | SIGLWP | Light-weight process信号。用于LWP线程的中断和终止。 |
61-63 | 保留 |
3. 信号的产生:
信号可以由多种事件和操作产生。常见的方式包括:
- 用户通过按键组合,如 Ctrl+C 发送 SIGINT 信号给前台进程。
- 用户通过终端按下
Ctrl+\
发送 SIGQUIT 信号给前台进程。 - 操作系统将某个特定的信号发送给进程,例如 SIGHUP 表示终端断开连接,SIGALRM 表示闹钟定时器到期等。
4. 信号的注册和注销:
进程可以使用 signal 函数来注册信号处理程序,用于捕获并处理特定信号。示例代码如下所示:
c
#include <stdio.h>
#include <signal.h>
void sig_handler(int signum) {
// 处理特定信号的逻辑
printf("Received signal: %d\n", signum);
}
int main() {
// 注册信号处理程序
signal(SIGINT, sig_handler);
// 执行其他操作
// 注销信号处理程序
signal(SIGINT, SIG_DFL);
return 0;
}
在上述示例中,通过调用 signal 函数来注册 SIGINT 信号的处理程序 sig_handler。当收到 SIGINT 信号时,会执行 sig_handler 函数中定义的逻辑。如果不再需要处理该信号,可以使用 signal 函数将处理程序设置为默认行为(SIG_DFL)。
5. 信号的处理:
进程收到一个信号时,可以按照以下方式进行处理:
- 忽略信号:使用 signal 函数将信号处理程序设置为 SIG_IGN,表示忽略该信号。
- 捕获并处理信号:使用 signal 函数将信号处理程序设置为自定义的信号处理函数,用于捕获并处理特定信号。
- 执行默认行为:使用 signal 函数将信号处理程序设置为 SIG_DFL,表示执行信号的默认行为。
需要注意的是,有些信号无法被忽略或捕获,如 SIGKILL 和 SIGSTOP。这些信号被用于强制退出进程和暂停进程的执行。