C 库函数 - sigaction()
sigaction
函数是 C 标准库中的一个函数,用于检查或修改与特定信号相关联的处理动作。与 signal
函数相比,sigaction
提供了更多的控制和更好的移植性。
语法
int sigaction(int sig, const struct sigaction *act, struct sigaction *oldact);
参数
int sig
:要检查或修改的信号编号。常见的信号包括SIGINT
、SIGTERM
、SIGKILL
等。const struct sigaction *act
:指向新的信号处理动作的指针。如果为NULL
,则不修改当前的信号处理动作。struct sigaction *oldact
:指向用于保存旧的信号处理动作的指针。如果为NULL
,则不保存旧的信号处理动作。
struct sigaction
结构体
struct sigaction { void (*sa_handler)(int); // 信号处理函数指针 void (*sa_sigaction)(int, siginfo_t *, void *); // 信号处理函数指针(扩展) sigset_t sa_mask; // 在处理该信号时要阻塞的信号集 int sa_flags; // 修改信号行为的选项 void (*sa_restorer)(void); // 恢复函数,已废弃 };
sa_flags
的常见选项
SA_RESTART
:使被信号中断的系统调用自动重新启动。SA_SIGINFO
:使用sa_sigaction
而不是sa_handler
作为信号处理函数。SA_NOCLDSTOP
:如果sig
是SIGCHLD
,则在子进程停止或继续时不产生该信号。
返回值
- 成功时返回 0。
- 失败时返回 -1,并设置
errno
以指示错误类型。
实例
以下是一个简单的示例程序,演示如何使用 sigaction
函数设置 SIGINT
信号的处理程序:
实例
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
// 自定义的信号处理函数
void handle_sigint(int sig) {
printf("Caught signal %d\n", sig);
}
int main() {
struct sigaction sa;
// 设置处理程序为 handle_sigint
sa.sa_handler = handle_sigint;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
// 使用 sigaction 设置新的信号处理动作
if (sigaction(SIGINT, &sa, NULL) == -1) {
perror("sigaction");
return 1;
}
// 主循环,持续运行直到捕捉到信号
while (1) {
printf("Running...\n");
sleep(1);
}
return 0;
}
#include <signal.h>
#include <unistd.h>
// 自定义的信号处理函数
void handle_sigint(int sig) {
printf("Caught signal %d\n", sig);
}
int main() {
struct sigaction sa;
// 设置处理程序为 handle_sigint
sa.sa_handler = handle_sigint;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
// 使用 sigaction 设置新的信号处理动作
if (sigaction(SIGINT, &sa, NULL) == -1) {
perror("sigaction");
return 1;
}
// 主循环,持续运行直到捕捉到信号
while (1) {
printf("Running...\n");
sleep(1);
}
return 0;
}
编译并运行程序后,输出将是:
Running... Running... Running... ...
当按下 Ctrl+C(发送 SIGINT
信号)时,输出将是:
Caught signal 2
程序捕捉到 SIGINT
信号并执行了自定义的信号处理函数 handle_sigint
,然后继续运行主循环。
注意事项
sigaction
函数提供了比signal
函数更丰富的功能,可以设置信号处理函数、信号掩码和信号处理选项。- 信号处理函数应尽量简短,因为在处理信号时会阻塞其他信号。如果信号处理函数运行时间过长,可能会影响程序的实时性。
- 某些信号(如
SIGKILL
和SIGSTOP
)不能被捕捉或忽略。