前言
如果,想要深入的学习Linux系统调用中的signal,sigaction函数,还是需要去自己阅读Linux系统中的帮助文档。
具体输入命令:
man 2 signal/sigaction
即可查阅到完整的资料信息。
signal 函数
signal()是一个用于处理Unix和类Unix操作系统(如Linux)中的信号的系统调用。信号是用于在进程间或者进程内部传递通知或者异常事件的机制。信号可以由用户按下某个键、硬件异常、软件中断或者其他进程产生。
signal()系统调用允许进程捕获、忽略或者改变特定信号的默认处理行为。
函数原型:
#include <signal.h> //使用此函数需导入此头文件
//该行代码定义了一个名为 sighandler_t 的新类型,
//这个新类型可以指向一个函数,函数无返回值,只有一个 int 类型的参数。
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
参数:
-
int signum
:指定要处理的信号。例如:SIGINT(终端中断)、SIGTERM(终止信号)等。 -
sighandler_t handler
:一个函数指针,用于处理特定的信号。可以是一个用户定义的函数,或者特殊值SIG_IGN(忽略信号)和SIG_DFL(使用默认处理行为)。
返回值:
- 如果成功,signal()返回之前的信号处理函数指针;否则,返回SIG_ERR,并设置errno以表示错误原因。
示例:
- 下面是一个简单的C程序,使用signal()捕获SIGINT信号(当用户按下Ctrl+C时产生)并执行自定义处理函数。
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
/*
在 C 语言中,函数的名称就是指向函数的指针,
因此 sigint_handler 代表函数自身的指针。
在这个程序中,我们希望将 sigint_handler 函数指针传递给 signal 函数,
使得 signal 函数在接收到 SIGINT 信号时,
能够调用到 sigint_handler 函数来处理该信号。
*/
void sigint_handler(int sig) {
printf("捕获到信号 %d\n", sig);
}
int main() {
signal(SIGINT, sigint_handler);
while (1) {
printf("等待信号...\n");
sleep(1);
}
return 0;
}
-
这个程序运行起来后,会每隔一秒循环输出等待信号…,你需要手动 Ctrl+C, 这个时候,这个进程捕捉到了这个SIGINT信号(也就是signal函数捕捉到了SIGINT信号),然后就会执行自定义的sigint_handler这个函数,而不是执行SIGINT信号默认执行的内容。
-
我们sigint_handler这个函数的作用是输出一句话,也就是说,用户每按一次Ctrl + C,就会输出
捕获到信号 SIGINT ,然后继续每隔一秒输出一次 等待信号…
请注意,signal()在不同的Unix和类Unix系统中的行为可能会有所不同。对于可移植性和更多功能,推荐使用sigaction()系统调用。
sigaction()函数
sigaction()是一个Linux系统调用,用于处理和控制信号。相比signal()函数,sigaction()提供了更强大且具有可移植性的信号处理能力。sigaction()可以让你定义捕获信号时的行为,包括设置信号处理函数和信号处理选项。
函数原型:
#include <signal.h> // 使用此函数,需导入此系统调用
int sigaction(int signum, const struct sigaction *restrict act, struct sigaction *restrict oldact);
参数:
-
int signum
:指定要处理的信号,例如:SIGINT(终端中断)、SIGTERM(终止信号)等。 -
const struct sigaction *restrict act
:一个指向sigaction结构体的指针,该结构体包含信号处理函数和信号处理选项。如果为NULL,则不会改变信号的处理行为。struct sigaction *restrict oldact
:一个指向sigaction结构体的指针,用于存储信号原有的处理行为。如果为NULL,则不会返回信号原有的处理行为。
返回值:
- 成功时,返回0;
- 失败时,返回-1,并设置errno以表示错误原因。
sigaction结构体:
struct sigaction {
void (*sa_handler)(int); // 信号处理函数,常用
void (*sa_sigaction)(int, siginfo_t *, void *); // 带有信号信息的信号处理函数,不常用
sigset_t sa_mask; // 在信号处理函数执行期间屏蔽的信号集
int sa_flags; // 控制信号处理行为的标志位,决定你到底是使用sa_handler还是sa_sigaction处理函数。
void (*sa_restorer)(void); // 已过时,不建议使用
};
- 在这里我觉得我得解释一下这个sa_mask,这个是一个临时的阻塞信号集,
它的作用仅仅是在执行某个信号的时候,才会去阻塞信号集中的信号,在除了执行某个信号的其他时间里,不会阻塞任何信号。
示例:文章来源:https://www.toymoban.com/news/detail-433915.html
- 下面是一个简单的C程序,使用sigaction()捕获SIGINT信号(当用户按下Ctrl+C时产生)并执行自定义处理函数。
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
void sigint_handler(int sig) {
printf("捕获到信号 %d\n", sig);
}
int main() {
struct sigaction sa;
sa.sa_handler = sigint_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if (sigaction(SIGINT, &sa, NULL) == -1) {
perror("sigaction");
exit(EXIT_FAILURE);
}
while (1) {
printf("等待信号...\n");
sleep(1);
}
return 0;
}
在这个示例中,我们设置了一个自定义的信号处理函数sigint_handler,用于在接收到SIGINT信号时执行。我们使用sigemptyset()初始化sa_mask,以防止在信号处理函数执行期间阻塞任何其他信号。sa_flags设置为0,表示我们使用默认的信号处理行为。最后,调用sigaction()设置信号处理函数。文章来源地址https://www.toymoban.com/news/detail-433915.html
到了这里,关于Linux系统调用之signal,sigaction函数 (捕捉指定的信号,自定义/默认处理该信号)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!