一、什么是信号?
信号是Linux中用于进程间通讯的基本机制,它是异步通知机制,即发送信号的进程无需等待接收信号的进程响应。信号常用于通知进程发生了某个事件,比如终止信号(SIGTERM)用于请求进程正常终止,中断信号(SIGINT)用于从终端键盘输入中断进程等。
二、常见信号及其含义:
Linux系统提供了多种信号,每个信号都有一个唯一的整数值用于标识,例如SIGINT表示中断信号。以下是一些常见信号及其含义:
SIGINT (2): 中断信号,通常由用户在终端输入Ctrl+C触发,用于请求进程终止运行。
SIGTERM (15): 终止信号,用于请求进程正常终止。
SIGKILL (9): 杀死信号,强制终止进程。
SIGUSR1 (10) 和 SIGUSR2 (12): 用户自定义信号,可由用户自行定义其含义。
三、信号处理方式:
Linux中的信号可以有三种处理方式:
忽略信号:进程可以通过将信号处理函数设置为SIG_IGN(即忽略)来忽略特定信号,通常对于一些不需要处理的信号使用这种方式。
捕捉信号:进程可以为特定信号注册信号处理函数,当接收到该信号时,系统会调用相应的处理函数进行处理。
默认处理方式:对于未显式处理的信号,系统将采用默认的处理方式。例如,SIGINT的默认处理方式是终止进程。
四、代码示例:
以下示例演示了如何在Linux中注册信号处理函数,并使用信号进行简单的进程间通讯。
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
// 信号处理函数
void signal_handler(int sig) {
if (sig == SIGINT) {
printf("Received SIGINT signal. Terminating.\n");
// 进行清理工作或退出进程
// ...
_exit(0);
} else if (sig == SIGUSR1) {
printf("Received SIGUSR1 signal. Custom signal handler.\n");
// 自定义信号处理动作
// ...
}
}
int main() {
// 注册信号处理函数
signal(SIGINT, signal_handler);
signal(SIGUSR1, signal_handler);
printf("Process PID: %d\n", getpid());
while (1) {
// 进程主循环
// ...
sleep(1);
}
return 0;
}
运行以上代码,在终端中使用Ctrl+C发送SIGINT信号给进程,进程会响应SIGINT信号并调用信号处理函数进行终止操作。而使用kill命令或其他进程向该进程发送SIGUSR1信号时,进程会调用信号处理函数执行自定义操作。
结论:
Linux信号是进程间通讯与事件处理的基石。通过信号,不同进程可以实现异步通知,响应特定事件,以及执行自定义动作。合理使用信号可以实现进程间的协作与通讯,同时也需要注意信号处理函数的设计和信号处理过程中的同步与安全性,以确保系统的稳定运行。