Linux进程通讯—信号处理
进程通讯—信号处理
signal
系统调用是 UNIX 和类 UNIX 系统(如 Linux)中用于处理信号的一个基础机制。信号是软件中断,它们可以被系统或者进程发送给另一个进程或线程,以通知它们发生了某个事件。这些事件可以是硬件中断(如外部设备请求服务)、软件异常(如除零错误)、用户请求(如用户请求停止进程)等。
1.基本用法
signal
函数的原型定义在 <signal.h>
头文件中,我们可以通过 signal 系统调用注册信号处理函数:
#include <signal.h>
// 信号处理函数声明
typedef void (*sighandler_t)(int);
/**
* signal 系统调用会注册某一信号对应的处理函数。如果注册成功,当进程收到这一
信号时,将不会调用默认的处理函数,而是调用这里的自定义函数
*
* int signum: 要处理的信号
* sighandler_t handler: 当收到对应的 signum 信号时,要调用的函数
* return: sighandler_t 返回之前的信号处理函数,如果错误会返回 SEG_ERR
*/
sighandler_t signal(int signum, sighandler_t handler);
2.性质
2.1注意事项
- 信号处理函数的行为:信号处理函数必须是简单的,并且必须是异步信号安全的。这意味着它只能调用异步信号安全的函数,不能执行那些可能导致死锁或数据竞争的操作,如修改全局变量(除非这些操作是原子的)。
- 不可重入性:如果信号处理函数在执行时被中断(例如,通过另一个信号),则原始的处理函数可能会再次被调用,这可能导致不可预测的行为。
- 信号掩码:在信号处理函数执行期间,会阻塞(或忽略)与当前信号相同的信号,以避免嵌套调用。但是,这不会影响其他信号。
- 可移植性问题:由于不同系统间对信号处理的实现细节可能存在差异,因此使用
signal
函数可能会导致可移植性问题。
2.2替代方案
由于 signal
函数存在上述的缺点,许多现代系统提供了更可靠的替代方案,如 sigaction
函数。sigaction
提供了更详细的控制,包括指定信号屏蔽集、获取信号处理函数以及设置信号处理选项等。
3.测试
//
// Created by root on 2024/9/16.
//
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
void sigint_handler(int signum){
printf("捕获到信号%d\n",signum);
exit(signum);
}
int main(int argc,char *argv[]){
if (signal(SIGINT,sigint_handler)==SIG_ERR){
perror("signal error");
exit(EXIT_FAILURE);
}
while(1){
sleep(1);
printf("你好\n");
}
return 0;
}
在这个示例中,当接收到 SIGINT
信号(通常由用户按下 Ctrl+C 产生)时,sigint_handler
函数会被调用,程序会打印一条消息并退出。
原文地址:https://blog.csdn.net/weixin_45706195/article/details/142292081
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!