当前位置: 首页 > news >正文

signal() -函数的详细使用说明

一、函数概述

signal()函数用于设置特定信号的处理方式。它允许程序在接收到特定信号时执行自定义的处理函数,或者采用默认的处理方式,也可以选择忽略该信号。

二、函数原型

void (*signal(int sig, void (*func)(int)))(int);

这个函数接收两个参数,返回一个函数指针。

三、参数说明

  1. sig
    • 这是一个整数参数,表示要处理的信号编号。常见的信号有SIGINT(通常由 Ctrl+C 产生)、SIGTERM(通常用于请求程序终止)等。不同的操作系统可能支持不同的信号集。
  2. func
    • 这是一个函数指针参数,指向一个信号处理函数。该函数接收一个整数参数(即信号编号),无返回值。
    • func可以取以下几种值:
      • SIG_DFL:表示使用默认的信号处理方式。不同的信号有不同的默认行为,例如,对于SIGINT,默认行为通常是终止程序。
      • SIG_IGN:表示忽略该信号。即当程序接收到该信号时,不进行任何特殊处理。
      • 一个用户自定义的函数指针,指向一个信号处理函数。这个函数将在接收到指定信号时被调用。

四、使用步骤

  1. 包含头文件:

    • 在使用signal()函数之前,需要包含<signal.h>头文件。
  2. 定义信号处理函数:

    • 如果要使用自定义的信号处理函数,需要先定义一个函数,其参数为整数类型(表示信号编号),无返回值。例如:
    void signal_handler(int signum) {// 在这里编写信号处理的代码
    }
    
  3. 调用signal()函数:

    • 在程序中合适的位置调用signal()函数,设置特定信号的处理方式。例如,设置对SIGINT信号的处理为调用自定义的signal_handler函数:
    signal(SIGINT, signal_handler);
    

五、注意事项

  1. 信号处理函数应该尽量简单快速,避免执行复杂的操作或长时间的阻塞操作,因为信号可能在任何时候中断程序的执行。如果信号处理函数执行时间过长,可能会影响程序的响应性。
  2. 信号处理可能会被其他信号中断,所以在信号处理函数中要考虑到这种情况。例如,如果在处理一个信号时,又接收到了另一个信号,可能需要采取适当的措施来确保正确的处理顺序。
  3. 不同的操作系统对信号的处理可能会有所不同,所以在跨平台开发时需要注意兼容性问题。
  4. 一旦设置了信号处理函数,它将在程序的整个生命周期内有效,除非再次调用signal()函数来改变信号的处理方式。

六、示例代码

以下是一个完整的示例代码,展示了如何使用signal()函数来处理SIGINT信号:

#include <stdio.h>
#include <signal.h>/*** @brief 异常信号中断*/
DT_PRIVATE void signal_handler(int signal)
{DT_ERR("!!!!!request reboot signal:%d\r\n", signal);sync();sleep(5);dt_reboot();
}/*** @brief 异常信号处理初始化*/
DT_PUBLIC void signal_init(void)
{signal(SIGPIPE, SIG_IGN);        /* 13 一个对端已经关闭的socket调用两次write, 第二次将会生成SIGPIPE信号, 该信号默认结束进程. */signal(SIGINT, signal_handler);  /* 2  来自键盘的中断信号 */signal(SIGABRT, signal_handler); /* 6  程序的异常终止,如调用 abort */signal(SIGBUS, signal_handler);  /* 7 总线错误(内存访问错误) */signal(SIGSEGV, signal_handler); /* 11 段非法错误(非法访问内存),如空指针*/signal(SIGTERM, signal_handler); /* 15 发送到程序的终止请求 */
}

在 C 语言中,常见的信号及其默认行为如下:

一、SIGINT(中断信号)

  1. 产生方式:通常由用户在终端按下 Ctrl+C 产生。
  2. 默认行为:终止程序。当程序接收到这个信号时,通常会立即停止运行,并进行一些清理工作(如果有必要)后退出。

二、SIGTERM(终止信号)

  1. 产生方式:可以通过命令行工具(如 kill 命令)发送给程序,也可能由操作系统在某些情况下发送。
  2. 默认行为:终止程序。与 SIGINT 类似,SIGTERM 也是请求程序终止,但它通常比 SIGINT 更“礼貌”,允许程序有机会进行一些清理工作后再退出。

三、SIGSEGV(段错误信号)

  1. 产生方式:当程序试图访问非法的内存地址(如访问未分配的内存、访问已释放的内存、越界访问等)时产生。
  2. 默认行为:终止程序并产生核心转储文件(core dump)。核心转储文件包含了程序在崩溃时的内存状态等信息,可以用于调试。

四、SIGABRT(异常终止信号)

  1. 产生方式:可以通过调用 abort()函数产生。
  2. 默认行为:终止程序并产生核心转储文件。这个信号通常用于表示程序出现了严重的错误,无法继续运行。

五、SIGFPE(算术异常信号)

  1. 产生方式:当程序进行非法的算术运算时产生,例如除以零、浮点数溢出等。
  2. 默认行为:终止程序并产生核心转储文件。

六、SIGHUP(挂起信号)

  1. 产生方式:当终端关闭或者与终端的连接丢失时,控制进程(通常是一个守护进程)会收到这个信号。
  2. 默认行为:如果程序没有对这个信号进行特殊处理,通常会终止。但对于守护进程,通常会重新读取配置文件、重新初始化等操作,以确保在终端关闭后仍能正常运行。

七、SIGPIPE(管道破裂信号)

  1. 产生方式:当一个进程向一个没有读端的管道写入数据时产生。
  2. 默认行为:终止程序。如果程序没有处理这个信号,写入操作会失败,并返回错误码 -1,同时触发 SIGPIPE 信号,导致程序终止。

这些信号在不同的操作系统上可能会有一些细微的差别,但总体上它们的行为是相似的。在编写程序时,可以根据需要使用 signal()函数或其他信号处理机制来改变这些信号的默认行为,以实现更灵活的程序控制和错误处理。


http://www.mrgr.cn/news/61159.html

相关文章:

  • 《HTML在网络安全中的多面应用:从防范攻击到安全审查》
  • HyperGNNs超图神经网络模型详解
  • 离线docker安装数据库(无法访问互联网),那么直接使用 docker pull mysql:latest
  • Vmware窗口大小无法改变问题
  • Colossal-AI:深度学习大规模分布式训练框架
  • 深入学习 Python 量化编程
  • 树莓集团:以数字化平台为基,构建智慧园区生态体系
  • UI设计软件全景:13款工具助力创意实现
  • Spring Boot 经典九设计模式全览
  • AI绘画:SD3.5来了,Flux又不行了?
  • 【JAVA】第四张_Eclipse创建Maven项目
  • 【PUCCH——Format和资源集】
  • SpringBoot 定时任务 @Scheduled 详细解析
  • CentOS7安装Docker-2024
  • 软考信息系统监理师 高分必背
  • 3. 无重复字符的最长子串
  • 虚拟现实辅助工程技术助力航空航天高端制造业破局
  • 3211、生成不含相邻零的二进制字符串-cangjie
  • 富格林:曝光可信经验击败陷阱
  • [ComfyUI]Flux 局部重绘,无需 ControlNet,原生就足够强大!
  • Java中的自动装箱(Autoboxing)和拆箱(Unboxing)机制
  • 学点高数-数学上的集合练习①-三讲一测
  • Excel 单元格小数点精确位数机制
  • NOIP-2022 题解
  • 人工智能在单细胞测序和空间转录组学中的最新研究进展|顶刊速递·24-10-28
  • 【专用名词的离线语音识别在2024年底的解决方法调查-会议签到的补充】