【LinuxC语言】信号的基本概念与基本使用

文章目录

  • 前言
  • 一、信号的概念
  • 二、信号的使用
    • 2.1 基本的信号类型
    • 2.2 signal函数
  • 总结


前言

在Linux环境下,信号是一种用于通知进程发生了某种事件的机制。这些事件可能是由操作系统、其他进程或进程本身触发的。对于C语言编程者来说,理解信号的基本概念和使用方法是非常重要的,因为它们可以用来实现进程间通信、处理异常情况以及实现一些高级功能。


一、信号的概念

信号是一种在UNIX和类UNIX操作系统中用于通知进程发生事件的机制。它们是一种异步通信方式,可以由操作系统、其他进程或者进程本身发送给目标进程。信号的本质是一种软件中断,它提供了一种简单而有效的进程间通信方式,用于处理异步事件。

每个信号都有一个唯一的数字标识符,称为信号编号。例如,常见的信号包括SIGINT(表示终端中断,通常由Ctrl+C发送)、SIGTERM(表示终止请求)和SIGSEGV(表示无效的内存访问)。操作系统提供了一套标准的信号,同时也允许用户自定义信号。

信号可以用于多种用途,包括但不限于:
处理用户输入:例如,在终端中按下Ctrl+C会发送SIGINT信号,通常用于终止正在运行的程序。
错误处理:某些异常情况,如无效的内存访问或除以零,会触发相应的信号,进而允许程序进行错误处理或者优雅地退出。
进程间通信:进程可以向其他进程发送信号,从而实现简单的进程间通信。
进程控制:通过发送不同的信号,可以控制目标进程的行为,例如启动、停止或重新加载。
总之,信号是UNIX系统中一种重要的进程间通信机制,它允许进程在某些事件发生时得到及时通知,并采取相应的措施。

想象一下你在做一件事情,突然间有人拍了拍你的肩膀,告诉你:“快停下来!”这个拍肩膀的动作就好比是信号,而你停下来的反应就是信号的作用。

在计算机世界里,信号就像是操作系统或者其他程序发出的一种消息,告诉你的程序说:“发生了某件事情!”这件事情可能是用户按下了某个键,或者出现了程序出错的情况,等等。

所以,信号的本质就是一种通知机制,用来告诉程序发生了什么事情,程序可以根据不同的信号做出相应的处理,就像你收到不同的消息,会有不同的反应一样。

二、信号的使用

2.1 基本的信号类型

以下是Linux系统中的全部信号及其相应的编号:

信号名称信号编号说明
SIGHUP1终端挂起或控制进程终止。
SIGINT2由键盘引起的中断,通常是用户按下Ctrl+C。
SIGQUIT3由键盘引起的退出,通常是用户按下Ctrl+\。
SIGILL4非法指令。
SIGTRAP5追踪或断点陷。
SIGABRT6异常终止条件,通常由abort函数发出。
SIGBUS7总线错误。
SIGFPE8浮点异常。
SIGKILL9无条件终止,无法被捕获或忽略。
SIGUSR110用户自定义信号1。
SIGSEGV11无效的内存引用。
SIGUSR212用户自定义信号2。
SIGPIPE13向无读取进程的管道写数据时触发。
SIGALRM14定时器到期。
SIGTERM15终止请求,用于优雅地终止进程。
SIGSTKFLT16协处理器栈错误。
SIGCHLD17子进程状态改变。
SIGCONT18继续执行停止的进程。
SIGSTOP19停止进程。
SIGTSTP20交互停止信号,通常由用户按下Ctrl+Z。
SIGTTIN21后台进程尝试读取标准输入。
SIGTTOU22后台进程尝试写入标准输出。
SIGURG23紧急情况的socket条件。
SIGXCPU24超出CPU时间限制。
SIGXFSZ25超出文件大小限制。
SIGVTALRM26虚拟定时器到期。
SIGPROF27进程控制定时器到期。
SIGWINCH28窗口大小调整。
SIGIO29异步IO事件。
SIGPWR30电源故障。
SIGSYS31非法系统调用。

2.2 signal函数

signal函数原型:

#include <signal.h>void (*signal(int signum, void (*handler)(int)))(int);

作用:

signal函数用于设置对特定信号的处理方式。通过该函数,可以指定当接收到指定信号时所要执行的处理函数。

参数:

  • signum:要设置处理方式的信号编号。
  • handler:处理该信号的函数指针,可以是一个函数或者SIG_IGN(忽略该信号)或SIG_DFL(使用默认处理方式)。

返回值:

signal函数返回一个函数指针,指向之前的信号处理函数。如果发生错误,则返回SIG_ERR(-1)。

示例代码:

下面是一个示例代码,演示了如何使用signal函数来设置对SIGINT信号的处理方式:

#include <stdio.h>
#include <signal.h>
#include <unistd.h>// 自定义信号处理函数
void sigint_handler(int signum) {printf("接收到SIGINT信号,即将退出...\n");// 这里可以执行一些清理操作exit(0);
}int main() {// 注册SIGINT信号的处理函数if (signal(SIGINT, sigint_handler) == SIG_ERR) {perror("无法注册SIGINT信号处理函数");return 1;}printf("按下Ctrl+C试试看!\n");// 无限循环,等待信号while (1) {sleep(1);}return 0;
}

在这里插入图片描述

在这个示例中,我们使用signal函数将SIGINT信号的处理方式设置为我们自定义的函数sigint_handler。当程序接收到SIGINT信号(即用户按下Ctrl+C)时,将会调用该函数来处理信号。


总结

通过学习信号的基本概念和使用方法,我们可以更好地编写可靠的Linux应用程序。通过注册信号处理函数,我们可以定义在收到特定信号时所采取的行动,从而实现进程的自定义行为。然而,要注意信号处理函数的编写应尽量简洁高效,避免在其中执行过多的操作,以确保信号处理过程尽可能快速地完成。此外,要注意在多线程程序中使用信号时可能引发的竞态条件和其他并发问题,因此在这种情况下需要额外的注意和谨慎。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/669486.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

利用github pages建立Serverless个人博客

利用github pages建立Serverless个人博客 概述 使用github pages&#xff0c;可以在github上部署静态网站。利用这个功能&#xff0c;可以很方便地实现个人博客的发布托管。 比如我的个人博客&#xff1a;Buttering’s Blog 对应代码仓库&#xff1a;buttering/EasyBlog: 自…

什么是流星烛台?昂首资本一分钟讲解

各位投资者&#xff1a;五一劳动节快乐&#xff01; 什么是流星烛台图&#xff1f;都有什么特征&#xff1f;今天Anzo Capital昂首资本一分钟给各位投资者讲解清楚&#xff01; 流星烛台图其实很好理解&#xff0c;就是类似流星的烛台图。流星烛台图看起来与流星相同&#x…

JetPack之ViewModel+LiveData

目录 一、概述二、LiveData 使用2.1 创建 LiveData 对象2.2 观察 LiveData 对象2.3 更新 LiveData 对象 三、编写 LiveData Demo3.1 不使用 LiveData3.2 使用 MutableLiveData3.3 使用 MediatorLiveData3.3.1 监听 2 个数据源的变化3.3.2 编写模拟 2 个数据源更新的代码 四、Vi…

张大哥笔记:引流108招,让天下没有难搞的流量

时至今日&#xff0c;流量有多重要不用我多说。 不管网络还是实体所有项目都需要引流。 赚钱的公式很简单: 流量产品赚钱。 产品可以是实物&#xff0c;也可以是服务&#xff0c;更可以是虚拟商品。 甚至有些时候&#xff0c;没有产品&#xff0c;只有流量&#xff0c;你也…

03.配置监控一台服务器主机

配置监控一台服务器主机 安装zabbix-agent rpm -ivh https://mirror.tuna.tsinghua.edu.cn/zabbix/zabbix/4.0/rhel/7/x86_64/zabbix-agent-4.0.11-1.el7.x86_64.rpm配置zabbix-agent,配置的IP地址是zabbix-server的地址&#xff0c;因为要监控这台主机 vim /etc/zabbix/zab…

今日分享【CSS中的经典使用】

经典双飞翼布局 先看效果 双飞翼布局要求&#xff1a; 1、header和footer各自占领屏幕所有宽度&#xff0c;高度固定。 2、中间的container是一个三栏布局。 3、三栏布局两侧宽度固定不变&#xff0c;中间部分自动填充整个区域。 4、中间部分的高度是三栏中最高的区域的高度。…

C语言 | Leetcode C语言题解之第70题爬楼梯

题目&#xff1a; 题解&#xff1a; int climbStairs(int n) {double sqrt5 sqrt(5);double fibn pow((1 sqrt5) / 2, n 1) - pow((1 - sqrt5) / 2, n 1);return (int) round(fibn / sqrt5); }

WebSocket 多屏同显和异显

介绍 多屏同显:通过在一个应用上进行操作之后,另一个应用也能跟着一起发生改变,例如app1播放了晴天这首音乐,那么app2也要同步播放这首音乐,确保所有屏幕显示的内容完全相同。多屏异显:每个屏幕可以显示不同的内容,或者在内容更新时存在一定的延迟,而不需要严格保持同步…

vue快速入门(五十七) 作用域插槽

注释很详细&#xff0c;直接上代码 上一篇 新增内容 作用域插槽实现表格删除数据 源码 App.vue <template><div id"app"><!-- 向子组件传值 --><MyTable :tableData"tableData"><!-- 接收子组件的传值&#xff0c;默认是对象格…

06.Git远程仓库

Git远程仓库 #仓库种类&#xff0c;举例说明 github gitlab gitee #以这个仓库为例子操作登录码云 https://gitee.com/projects/new 创建仓库 选择ssh方式 需要配置ssh公钥 在系统上获取公钥输入命令&#xff1a;ssh-keygen 查看文件&#xff0c;复制公钥信息内…

【软考高项】三十一、成本管理4个过程

一、规划成本管理 1、定义、作用 定义&#xff1a;确定如何估算、预算、管理、监督和控制项目成本的过程作用&#xff1a;在整个项目期间为如何管理项目成本提供指南和方向 应该在项目规划阶段的早期就对成本管理工作进行规划&#xff0c;建立各成本管理过程的基本框架&…

一款 NodeJS 版本管理工具 NVM (Windows)

一、简介 Node Version Manager&#xff08;NVM&#xff09;是一种用于管理多个 NodeJS 版本的工具。在日常工作中&#xff0c;我们可能同时在进行多个不同的项目开发&#xff0c;每个项目的需求不同&#xff0c;依赖与不同版本的NodeJS 运行环境。这种情况下&#xff0c;维护…