Linux 系统中的信号捕获与处理

在 Linux 系统中,信号(Signal)是一种用于进程间通信的机制,它是一种异步的、非阻塞的通知,可以用来通知进程发生了某个事件,信号可以是硬件产生的,如中断,也可以是软件产生的,如系统调用。
信号的种类
Linux 系统中定义了多种信号,以下是一些常见的信号及其编号:
- SIGHUP:挂起信号,通常用于终止一个守护进程。
- SIGINT:中断信号,通常由用户按下 Ctrl+C 产生。
- SIGTERM:终止信号,用于正常终止一个进程。
- SIGALRM:定时器信号,当定时器到期时产生。
- SIGUSR1 和 SIGUSR2:用户自定义信号,可用于进程间的通信。
信号捕获
在 Linux 系统中,可以使用 signal() 函数来捕获信号,以下是一个简单的示例:

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void signal_handler(int signum) {
printf("捕获到信号 %d\n", signum);
}
int main() {
signal(SIGINT, signal_handler);
while (1) {
printf("程序正在运行...\n");
sleep(1);
}
return 0;
}
在上面的代码中,我们定义了一个信号处理函数 signal_handler,它会在接收到 SIGINT 信号时被调用,在 main 函数中,我们使用 signal() 函数将 SIGINT 信号与 signal_handler 函数关联起来。
信号屏蔽
在某些情况下,我们可能需要屏蔽某些信号,以避免在信号处理函数中再次接收到该信号,这可以通过 sigprocmask() 函数实现:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void signal_handler(int signum) {
printf("捕获到信号 %d\n", signum);
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGINT);
sigprocmask(SIG_BLOCK, &set, NULL);
}
int main() {
signal(SIGINT, signal_handler);
while (1) {
printf("程序正在运行...\n");
sleep(1);
}
return 0;
}
在上面的代码中,我们在 signal_handler 函数中使用 sigprocmask() 函数屏蔽了 SIGINT 信号,这样在信号处理函数执行期间,即使再次接收到 SIGINT 信号,也不会触发信号处理函数。
信号处理函数的替代方法

除了使用 signal() 函数外,还可以使用 sigaction() 函数来捕获信号。sigaction() 函数提供了比 signal() 更丰富的功能,例如可以设置信号处理函数的优先级。
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void signal_handler(int signum) {
printf("捕获到信号 %d\n", signum);
}
int main() {
struct sigaction sa;
sa.sa_handler = signal_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGINT, &sa, NULL);
while (1) {
printf("程序正在运行...\n");
sleep(1);
}
return 0;
}
在上面的代码中,我们使用 sigaction() 函数替代了 signal() 函数,以捕获 SIGINT 信号。
Linux 系统中的信号捕获与处理是进程间通信的重要机制,通过合理地使用信号,可以有效地实现进程间的同步和通信,本文介绍了信号的基本概念、种类、捕获方法以及信号屏蔽等知识,有助于读者更好地理解和应用 Linux 系统中的信号机制。


















