Unix环境高级编程(三)信号专题(1)

本文深入探讨了Unix环境下的信号处理机制,从信号的基本概念出发,介绍了信号与中断的区别与联系,详细列举了常见信号及其作用,并通过编程示例展示了如何在程序中捕获和处理信号。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Unix环境高级编程(三)信号专题(1)

原文连接:访问原文

中断的概念

要了解信号的概念,先要了解什么是中断?中断是系统对于异步事件的响应,所谓异步事件的响应就是指:

进程执行代码的过程中可以随时被打断,然后去执行异常处理程序生活中的中断和计算机系统中的中断。

中断的组成包括:

中断信号
* 中断源
* 现场信息
* 中断处理程序
* 中断向量表

这和我们生活中的一些例子很像,比如:张三看书,设置闹钟,厨房烧水。闹钟发出中断信号,张三把书合好(第20页),去厨房把开水事情处理好,张三重新打开20页进行阅读。

其中中断分为两类:硬中断和软中断
硬中断也称外部中断,是指由外部设备通过硬件请求的方式产生的中断,也称为硬件中断。
软中断也称内部中断,是由CPU运行程序错误或执行内部程序调用引起的一种中断,也称为软件中断。

信号的概念

信号是在软件层次上对中断的一种模拟,所以通常把它称为是软中断。
首先,每个信号都有一个名字。这些名字都以三个字符SIG开头。例如,SIGABRT是夭折信号,当进程调用abort函数时产生这种信号。
信号的定义在头文件<signal.h>中这些信号都被定义为正整数,范围在1~64。其中1~32号信号是不可靠信号,33~64为前32种不可重入信号的可靠版本,其名称在不可靠信号名称加R。我们可以通过命令kill -l来查看Linux内核支持的信号,64中信号如下:
enter description here

信号和中断的异同

  • 信号与中断的相似点:
    1. 采用了相同的异步通信方式;
    2. 当检测出有信号或中断请求时,都暂停正在执行的程序而转去执行相应的处理程序;
    3. 都在处理完毕后返回到原来的断点;
    4. 对信号或中断都可进行屏蔽。
  • 信号与中断的区别:
    1. 中断有优先级,而信号没有优先级,所有的信号都是平等的;
    2. 信号处理程序是在用户态下运行的,而中断处理程序是在核心态下运行;
    3. 中断响应是及时的,而信号响应通常都有较大的时间延迟。

信号名称及常用信号

信号名称描述
SIGABRT进程停止运行
SIGALRM警告钟
SIGFPE算述运算例外
SIGHUP系统挂断
SIGILL非法指令
SIGINT终端中断
SIGKILL停止进程(此信号不能被忽略或捕获)
SIGPIPE向没有读者的管道写入数据
SIGSEGV无效内存段访问
SIGQUIT终端退出
SIGTERM终止
SIGUSR1用户定义信号1
SIGUSR2用户定义信号2
SIGCHLD子进程已经停止或退出

信号的处理

进程对信号有三种处理:
1. 忽略信号
不采取任何操作、有两个信号不能被忽略:SIGKILL(9号信号)和SIGSTOP。
2. 捕获并处理信号
内核中断正在执行的代码,转去执行先前注册过的处理程序。SIGKILL(9号信号)和SIGSTOP不能被捕获。
3. 执行默认操作
默认操作通常是终止进程,这取决于被发送的信号。

这里要理解为什么以上两种信号(SIGKILL和SIGSTOP)不能被忽略。其原因是:如果应用程序可以忽略这2个信号,系统管理无法杀死、暂停进程,无法对系统进行管理。

signal函数

signal函数有两个作用:
1. 站在应用程序的角度,注册一个信号处理函数;
2. 忽略信号、设置信号默认处理 信号的安装和恢复。

其函数定义如下:

#include <signal.h>

typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler);

signum指定信号种类,handler指定信号的处理函数,也可以是下面两个特殊值:SIG_IGN(屏蔽该信号)和 SIG_DFL(恢复默认行为)。
signal返回原先的信号处理句柄,出错时返回SIG_ERR,并设置error值。

singnal编程实战

我们先来写一个信号处理函数,这个信号处理函数,实现打印信号值得功能,并且判断信号是否是SIGQUIT,如果是就退出进程。

void handler(int num)
{
    printf("recv num:%d \n", num);
}

在主函数中,我们注册此信号,并使进程进入暂停此时用户按(ctrl+c)将执行打印函数,程序无法退出,直到用户键入字符‘a’为止,我们让信号恢复默认行为,再执行==ctrl+c==时,程序退出。

void main()
{
    char   tmpchar;
    signal(SIGINT, handler);

    printf("if you input 'a' will recove the default behavior of signal\n");
    while((tmpchar = getchar()) != 'a')
    {
        pause();
    }

    //让这个信号恢复默认行为
    signal(SIGINT, SIG_DFL);
    while(1)
    {
        pause();
    }
    printf("main----end\n");
}
内容概要:本文介绍了奕斯伟科技集团基于RISC-V架构开发的EAM2011芯片及其应用研究。EAM2011是一款高性能实时控制芯片,支持160MHz主频和AI算法,符合汽车电子AEC-Q100 Grade 2和ASIL-B安全标准。文章详细描述了芯片的关键特性、配套软件开发套件(SDK)和集成开发环境(IDE),以及基于该芯片的ESWINEBP3901开发板的硬件资源和接口配置。文中提供了详细的代码示例,涵盖时钟配置、GPIO控制、ADC采样、CAN通信、PWM输出及RTOS任务创建等功能实现。此外,还介绍了硬件申领流程、技术资料获取渠道及开发建议,帮助开发者高效启动基于EAM2011芯片的开发工作。 适合人群:具备嵌入式系统开发经验的研发人员,特别是对RISC-V架构感兴趣的工程师和技术爱好者。 使用场景及目标:①了解EAM2011芯片的特性和应用场景,如智能汽车、智能家居和工业控制;②掌握基于EAM2011芯片的开发板和芯片的硬件资源和接口配置;③学习如何实现基本的外设驱动,如GPIO、ADC、CAN、PWM等;④通过RTOS任务创建示例,理解多任务处理和实时系统的实现。 其他说明:开发者可以根据实际需求扩展这些基础功能。建议优先掌握《EAM2011参考手册》中的关键外设寄存器配置方法,这对底层驱动开发至关重要。同时,注意硬件申领的时效性和替代方案,确保开发工作的顺利进行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值