📅  最后修改于: 2023-12-03 14:48:13.524000             🧑  作者: Mango
在 Unix 操作系统中,信号是一种处理异步事件的机制。当一个进程接收到一个信号时,可以选择忽略信号、执行默认操作或自定义操作。
Unix 操作系统中有许多不同的信号,下面是一些常见的信号:
SIGINT
:键盘中断信号,通常由用户使用 Ctrl + C
触发。SIGTERM
:终止信号,用于请求一个进程正常退出。SIGKILL
:杀进程信号,用于立即终止一个进程。SIGSEGV
:段错误信号,通常由访问未分配内存或非法内存引起。可以使用 kill
命令向指定进程发送信号:
kill -<signal> <pid>
其中 <signal>
是信号名称或编号,<pid>
是进程 ID。
程序员可以使用 signal
函数来注册信号处理程序,例如:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
void sigint_handler(int signal) {
printf("\nCaught SIGINT, exiting...\n");
exit(0);
}
int main() {
signal(SIGINT, sigint_handler);
printf("Running...\n");
while (1) {}
return 0;
}
上述程序注册了一个 SIGINT
信号处理程序,当用户按下 Ctrl + C
时,程序将输出一条消息并退出。
还可以使用 sigaction
函数注册信号处理程序,它比 signal
更加可靠和灵活。
除了显示地处理信号外,进程还可以忽略某些信号或使用信号捕捉阻止某些系统调用被打断。这需要使用 sigprocmask
函数来设置信号掩码。
在 Unix Shell 中,将某个命令放在圆括号中可以将该命令放在一个子 shell 中执行,而且在子 shell 中运行的变量不会影响父 shell 中的变量。例如:
(a=1; echo $a) # 输出 1
echo $a # 输出空
但是,子 shell 中定义的信号处理程序可能会影响父 shell。当子 shell 注册一个信号处理程序时,它实际上是将该处理程序安装到内核中。但是,当子 shell 退出时,它的处理程序并没有被卸载,可能会影响父 shell 中的信号处理。
因此,在使用子 shell 时,需要小心处理信号。