信号:进程间通信与异步事件处理的关键机制

本文详细阐述了操作系统中信号的作用,包括信号在进程间通信中的应用,如何处理不可忽视的信号和捕获信号,以及信号处理流程。同时强调了信号处理中的重入问题和信号安全,提醒开发者注意并发问题的防范。
摘要由CSDN通过智能技术生成

信号是操作系统中一种重要的通信机制,它允许进程之间通过发送软件中断来传递信息,从而实现异步事件的处理。信号提供了进程间通信(IPC)的一个基本手段,允许系统或进程在特定事件发生时通知另一个进程。在Unix/Linux系统中,信号的定义和管理通过signal.h头文件进行,总共定义了62个信号,分为不可靠的非实时信号(前31个)和可靠的实时信号(后31个)两大类。

 信号的处理方式

忽略信号

并非所有信号都能被忽略,如SIGKILL(9)和SIGSTOP(19)这两个信号,它们分别用于强制结束进程和停止进程,不能被进程忽略。

默认处理

如果未显式设置信号处理方式,系统将采取默认动作,例如终止进程或忽略信号。

捕获信号

通过自定义信号处理函数,进程可以捕获信号并在特定信号到达时执行预设的代码逻辑,之后再恢复原执行流程。

信号处理流程

当信号到达时,内核会保存当前进程的上下文,执行信号处理函数,处理完成后恢复现场,使进程继续执行原有任务。

//信号处理
#include<stdio.h>
#include<signal.h>
#include<unistd.h>

typedef void (*sighandler_t)(int);
void handler(int signum){
    printf("成功捕获%d号信号了!\n",signum);

}
int count = 1;

int main(void){
    //这个地方第一次处理(忽略)二号信号,会返回null
    sighandler_t ret = signal(SIGINT,SIG_IGN);
    if(ret==SIG_ERR){
       perror("signal");
       return -1;
    }
    printf("ret = %p\n",ret);
    
    //这里第二次处理二号信号
    sighandler_t ret2 = signal(SIGINT,handler);
    printf("ret2 = %p\n",ret2);
    
    //sighandler_t ret3 = signal(SIGINT,SIG_IGN);
    
    //printf("ret3 = %p\n",ret3);
    
    for(;;){
        printf("当前循环次数%d\n",count++);
        sleep(1);
    };

    return 0;
}

重入问题与信号安全 

信号处理函数在执行过程中若遇到自身被再次调用的情况,称为“重入”。这可能导致全局变量、静态变量等共享资源的不一致问题,因为信号处理函数的执行可能会打断对这些资源的正常访问流程。因此,编写信号处理函数时应避免访问全局或静态变量,以保证信号处理的原子性和安全性。

太平间信号:SIGCHLD

当子进程结束时,系统向其父进程发送SIGCHLD(17)信号,父进程可在信号处理函数中异步回收子进程资源,避免僵尸进程的产生。然而,如果信号处理函数执行时间过长,可能导致后续相同信号的丢失,因为Linux系统默认对重复的实时信号不累积处理。

 总结

信号作为一种强大的异步事件处理机制,在Unix/Linux系统编程中扮演着重要角色。通过合理设置信号处理方式,开发者可以有效地响应系统事件、实现进程间通信及管理进程生命周期。然而,信号处理也需谨慎,特别是要关注重入问题和信号处理函数的安全性,以避免潜在的并发问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值