信号使用以及处理

【Linux】信号的理解以及信号集处理函数的使用 信号产生方式 通过终端按键产生。 如ctrl+c 终止进程 通过系统函数向进程发送信号。如kill()函数,给指定进程发送信号。 有软件条件产生信号。如alarm()函数,设定一个闹钟信号。 硬件异常。如内存越界,除0异常。 利用kill()函数实现自己的kill 命令// 发送信号给进程 #include <sys/types.h> #include <signal.h>int kill(pid_ 阅读详情
信号使用以及处理
一、引子
在我们的生活中,时时刻刻的在产生着信号,比如朋友之间昵称的问候,老师学生之间提问的表达等等,都是信号的一种具体体现,那么在Linux应用实现的底下,我们是怎么样去使用和认识它,处理它的呢。

二、信号的概念:
信号是UNIX和Linux系统下响应某些条件而产生的一个事件。接收到该信号的进程会相应地采取一些行动,我们平常用术语【生成】(raise)表示一个信号的产生,术语【捕获】(catch)来表示接收到一个信号。一般一个信号的发生,是由于发生了一些不可避免的错误来发送给相应的进程,使之进行处理。而信号可以产生也可以接收,产生和接收的主体都是进程。
信号在系统中的定义为:
/usr/include/bits/signum.h  

信号的名称是在signum.h中定义的,它们以SIG开头进行定义:也从而看出这些信号在底层是通过宏定义的


上述是信号的一些底层定义,接着我们看一下信号的一些说明:

如图所示:


重点说明上述的信号SIGKILL,它是用来终止进程的,但是最重要的还是这个信号的不允许修改它的响应方式,至于响应方式下面将会进行说明;而上面的SIGINT信号可以通过在shell和终端驱动程序按通常的情况配置的话,可以通过键盘敲入中断字符(通常是Ctrl+c组合键)向前台进程(即当前正在运行的程序)发送这个信号(即SIGINT信号),这将引起该程序的终止,除非它事先安排了捕获这个信号。

如果进程接收到这些信号的中的一个,但事先没有安排捕获它,进程将会立即终止。通常,系统将生成核心转储文件core,并将其放在当前目录下,该文件是进程在内存中的映像,它对程序的调试很有用处。


所谓核心转储文件是内含进程终止时内存映像的一个文件。

产生条件:特定的信号会引发进程创建一个核心转储文件并终止运行。


(重点)SIGCHLD信号对于管理子进程很有用,为什么这么说呢,因为子进程结束时会自动向其父进程发送 SIGCHLD 信号,这样可以避免产生僵尸进程,前面博客已经说了僵尸进程的危害和产生僵尸进程的原因了,从而看出SIGCHLD这个信号的“强大之处”。默认情况下,它是被忽略的,其余的信号会使接收它们的进程停止运行,但SIGCONT是个例外,它的作用是让进程恢复并继续运行。shell脚本通过它来控制作业,但用户程序很少使用它。


三、信号的使用以及处理

说之前首先提出:

1、 信号是怎样发送的 2、 信号是怎样接受的 3、 信号接收以后做了什么事情

对于信号的处理我们是用signal这个库函数实现的,它的定义如下:
#include
typedef void (*Fun_Handle)(int);

Fun_Handle signal(int signum, Fun_Handle fun);  

Linux定义如下:借助命令:    man   signal.h      可以查看signal函数的定义。

这个函数的定义说明,signal函数是一个带有整型的signum和一个类型为函数指针的fun共两个参数组成的函数。准备捕获或忽略的信号由signum给出,接收到的信号后要将调用的函数由参数fun给出,信号处理函数(fun)必须要有一个int类型的参数,即接收到的信号代码,并且返回类型为void,signal函数本身也会返回一个同类型的函数,即先前用来处理这个信号的函数。

这里我们说一下除了上述的自定义函数fun还有两个。而第二个参数相当于说成捕获吧。它是信号的一种响应方式。那么信号的响应方式分为哪一种呢

信号的响应方式:
分为三种:     
默认行为 : SIG_DFL
忽略信号 : SIG_IGN
自定义信号: 自定义函数

signal 函数功能: 完成 signum 参数执行的信号与 fun 函数绑定, 当接收到 signum 这个信号, 执行 fun 这个函数。  

signal函数出差错的特殊处理及说明:signal函数返回的是先前对指定信号进行处理的信号处理函数的指针,如未定义信号处理函数,则返回SIG_ERR并设置errno 为一个正数值,如给出一个无效的信号,或者尝试处理的信号是不可捕获或者不可忽略的信号(如SIGKILL),errno将设置为EINVAL;

总体而言信号的发送是通过函数signal中参数函数指针,指向fun这个函数,而信号处理函数fun对signal函数第一个参数signum传递进来的信号作出响应,信号出现时,信号调用该函数(fun函数,也就是signal函数的第二个参数函数指针所指向的函数),实现fun函数里面的功能,下面我们将举例说明:

编程题一:
编写程序实现:当进程第一次接收到 SIGINT 信号后,打印“i  got  signal  ”!  ,并且通过fun()函数打印signal第一个参数signum信号的值;

实现代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>

void fun(int sig)
{
	printf("i got signal %d\n",sig);
}

void main()
{
	signal(SIGINT,fun);
	while (1)
	{
		printf("i am go to main\n");
		sleep(1);
	}
}

结果如下:


分析:通过上面实例发现,它将响应ctrl+c组合键,也就是信号SIGINT信号,当fun这个函数处理信号SIGINT的时候,打印信号SIGINT的值和一串字符"i  got   signal" ,函数fun对参数signum传递进来的信号做出响应,信号出现时,程序调用该函数,fun函数执行完打印后,然后将信号SIGINT(默认情况下,按下CTRL+C将产生这个信号)的处理方式恢复为默认行为。main()函数的作用是,截获按下CTRL+C组合键产生的SIGINT信号,没有信号时,它会子啊一个无限循环中每隔一秒打印一条信息。每一次按下CTRL+C组合键会让程序做出响应,然后程序继续执行。(重点)从而说明signal这个函数是由底层操作系统内核实现完成的,它与main函数是各自执行自己的互不干扰。

看下图signal在帮助手册定义:


(重点):左上角(右上角)signal(2)里面的2就说明这signal函数是由系统内核完成的,只供给用户使用的时候一个用户接口。下面是signal的帮助手册定义。并且在调用signal函数时,它的第二个参数:函数指针,不是在调用,而是相当于一个函数地址,把这个地址传给了signal函数,供它使用,函数调用是signal()  ,而我们上面所写明显没有()从而说明它是一个函数地址(函数指针)。

编程题二:
编写程序实现:当进程第一次接收到 SIGINT 信号后,打印“sig =  ”,主函数打印hello!第二次接收到SIGINT 信号后, 结束进程。  

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <string.h>
#include <signal.h>


void fun(int sig)
{
	printf("sig = %d]\n",sig);
	signal(SIGINT,SIG_DFL);

}

int main(int argc,char *argv,char *envp)
{
	signal(SIGINT,fun);
	while(1)
	{
		printf("hello\n");
		sleep(1);
	}
}

结果如下:


分析:第一次按下CTRL+C 组合键会让程序做出响应,程序会在中断函数fun()处理完毕然后程序继续运行,再次按下CTRL +C的时候,程序将终止,也就是程序将结束运行,因为SIGINT信号的处理方式已恢复默认行为---终止程序的运行,sig = 2 就是SIGINT信号在底层定义宏的值,从而说明信号处理函数fun(int sig)默认参数为int  sigum ,且信号处理函数使用了一个单独的整形参数,它就是引起该函数调用的信号代码。如果需要在同一个函数中处理多个函数,这个参数就很有用,在这个例子中,我们打印了SIGINT的值,它的值在系统中定义是数字2,但不要过于依赖传统的信号数字值,而应该在新的程序中总是使用信号的名字。
       
如果想保留信号处理函数,让它继续响应用户的CTRL+C 组合键,我们就要再次调用signal函数来重新建立它,这会使信号在一段时间内无法得到处理,这段时间从调用中断函数开始,到信号处理函数的重建为止,如果在这段时间内程序接收到第二个信号,它会违背我们的意愿将程序终止程序的运行。

如果第一次接收到信号, 进入信号处理函数, 执行 10 秒钟, 主程序不会同时执行, 主程序会等待信号处理函数执行完成后, 接着运行。
如果信号处理函数正在执行, 信号被再次触发, 则第二次触发的信号会被放到信号的等待队列中, 直到之前的信号处理函数执行完成, 才会被处理。  

正确处理常识: 在信号处理函数中,调用如printf这样的函数是不安全的,一个有用的技巧是,在信号的处理函数中设置一个标志,然后再主程序中检查该标志,如需要就打印一条信息。

数字信号处理Python示例(1)使用Python生成正弦信号 介绍如何使用python生成正弦信号,给出详细步骤和完整的python代码和运行结果。这是《数字信号处理python示例》系列文章的第一篇。整个系列将使用python编程示例说明数字信号处理的基本原理与工程应用。给出的所有Python程序将努力做到简单且具有说明性。在数字信号处理的理论方法,将注重其实际意义和工程应用方面的介绍,而避免其数学上的推导与证明。 阅读详情

相关推荐

C语言信号处理:使用sigaction函数处理信号

其中,sigaction函数是一种用于注册信号处理函数的高级方法,它提供了更多的灵活性和可靠性。需要注意的是,信号处理函数应该是短小且非阻塞的,因为它们是在不可预测的时刻被调用的。在信号处理函数中,应该尽量避免使用不可重入函数和标准I/O函数。接下来,我们定义一个信号处理函数,用于处理特定信号的触发。在本文中,我们将探讨如何使用sigaction函数来处理信号,并提供相应的源代码示例。然后,在主函数中注册信号处理函数,使用sigaction函数来捕获SIGINT信号。函数注册了信号处理函数。

KxobDebugging的博客 358

signal 使用介绍

文章目录一、signal 信号简介二、signal 产生方式1. 用户操作终端2. 硬件异常3. 软件异常4. 调用 `kill()` 函数或者执行 `kill` 命令三、signal 基本函数1. `int kill(pid_t pid, int signum);`2. `int pause(void);`3. `signal(int signum, sighandler_t handler);`4. `int sigqueue(pid_t pid, int sig, const union sigval

chenwh_cn的博客 6784

音频信号处理:使用MATLAB进行信号处理

本文介绍了如何使用MATLAB进行音频信号处理的基本步骤,包括读取音频信号、播放音频信号、可视化音频信号、应用滤波器和增益控制。本教程介绍了如何使用MATLAB进行音频信号处理的基本步骤,包括读取音频信号、播放音频信号、可视化音频信号、应用滤波器和增益控制。在上述代码中,我们将音频信号的增益设置为2,然后将其应用于原始音频信号,得到增益控制后的音频信号。在上述代码中,我们将音频信号的增益设置为2,然后将其应用于原始音频信号,得到增益控制后的音频信号。上述代码将绘制音频信号的波形图和频谱图。

RmAlgorithm的博客 1348

信号的介绍及使用

1.什么是信号 (1)信号是内容受限制的一种异步通信机制 (2)信号的目的是用来通信 (3)信号是异步的(对比硬件中断) (4)信号本质上是int型数字编号(事先定义好的) 2.信号由谁发出 (1)用户在终端按下按键 (2)硬件异常后由操作系统内核发出信号 (3)用户使用kill命令向其他进程发送信号 (4)某种软件条件满足后也会发出信号,如alarm闹钟时间到会产生SIGALARM信号,向一个读端已经关闭的管道write时会产生SIGPIPE信号 3.信号由谁处理、如何处理 (1)忽略信号 (2)捕捉信号

weixin_54989626的博客 1775

多进程:使用信号量进行监听和处理函数的信号处理

在多进程编程中,信号量是一种常用的同步机制,可以用于实现进程之间的互斥和同步。通过使用信号量,我们可以监听并处理进程间发送的信号。在本文中,我们将探讨如何使用信号量来监听和处理函数的信号处理。当父进程发送信号时,子进程将接收到信号并调用处理函数。接下来,我们创建一个子进程,并在其中使用信号量进行监听。子进程将等待信号量的释放,并在接收到信号后调用处理函数。接下来,我们定义一个处理函数,用于处理接收到的信号。然后,我们创建一个信号量对象,并将处理函数与信号量绑定。首先,我们需要导入必要的模块,包括。

QqdwPhp的博客 135

常用C信号处理函数 常用C信号处理函数

c的多线程中的信号处理常用函数c的多线程中的信号处理常用函数c的多线程中的信号处理常用函数c的多线程中的信号处理常用函数

7,信号使用

07 信号 1 学习目标 了解信号中的基本概念 熟练使用信号相关的函数 参考文档使用信号集操作相关函数 熟练使用信号捕捉函数signal 熟练使用信号捕捉函数sigaction 熟练掌握使用信号完成子进程的回收 信号介绍 信号的概念 信号是信息的载体,Linux/UNIX 环境下,古老、经典的通信方式, 现下依然是主要的通信手段。 信号在我们的生活中随处可见,例如: 古代战争中摔杯为号; 现代战争中的信号弹; 体育比赛中使用的信号枪… 信号的特点 简单 不能携带大量信息 满足某

qq_44840256的博客 202

STM32+OpenCV云台PID调参实战:从震荡到丝滑跟踪的进阶之路

本文详细介绍了基于STM32和OpenCV的跟踪云台PID调参实战经验。从硬件搭建、PID控制原理到调参技巧,系统讲解了如何通过调整比例、积分和微分参数解决系统震荡问题,实现从震荡到丝滑跟踪的进阶过程,特别适合电赛和嵌入式视觉控制开发者参考。

tgb3456789的博客 715

Linux 信号总结以及常见信号使用

【摘要】信号是学习linux时必须要熟悉的一部分,没有了信号Linux系统就没办法正常的工作。而我们作为Linux程序员,也要用到信号来进行程序的运行,没有了信号,我们的工作将会变得一团糟。这几天,我把刚刚学的关于信号的知识点总结了一下,分享给大家,希望可以对大家有所帮助。信号的概念信号是linux系统为了响应某些状况而产生的事件。进程收到信号后应该采取相应的动作哪些情况会引发信号1.键盘事件  ...

努力努力再努力的博客 1万+

Cadence 17.2 OrCAD原理图库实战:从零创建电阻/电容/LED元件(附封装技巧)

本文以Cadence 17.2 OrCAD为核心,详细讲解了如何从零开始工程化地创建电阻、电容、LED等原理图库元件。内容涵盖库架构设计、符号绘制、引脚属性管理、封装关联技巧以及设计规则检查,旨在帮助硬件工程师构建规范、可复用且易于维护的元件库,为高效PCB设计奠定坚实基础。

weixin_29195615的博客 400

ifix5.8连接ab plc的点-通过rslinx

以ifix连接ab plc的点为例 1.先在rslinx上把plc的点导出为opc server 2.使用opc power tool 作为opc client 去连接 3.保存到项目的PDB文件夹下面,并且以节点名命名。 也可以不以节点名命名,系统自动会生成一个以节点名命名的这种文件,就显得很乱。 同时,项目的PDB目录下面必须还得拷过来一个de...

中国智造2025 4110

信号使用方法

信号基本使用方法 信号: 首先计算机是一个很会营造假象的机器,它欺骗每一个进程,线程。使他们误以为自己就是唯一使用资源的进线程,但是者也造成了一个问题,进线程们都变得比较自我,想让他们互相之间通信,或者我们和他们通信就必须使用一些 “手段“ 。向他们发送信号就...

weixin_30609331的博客 202

将Apollo高精地图中的车道线叠加在多种导航地图上

本文介绍了将Apollo高精地图车道线叠加到普通导航地图的技术方案。高精地图具备厘米级车道精度和丰富的语义信息,叠加可实现可视化验证、调试分析和数据对比等功能。核心技术包括坐标系统转换(UTM/WGS84/BD09/GCJ02)和数据处理流程,通过Python脚本完成Apollo地图解析、坐标批量转换和多格式输出。文章详细提供了环境准备、工作目录创建和坐标转换脚本等操作步骤,实现了高精地图数据在OpenStreetMap、百度地图和高德地图上的可视化展示。

Hi20240217的博客 1332

使用sigaction处理内核信号

文章目录函数描述函数使用抓取发送信号的进程信息 mark一次获取内核信号,并作相应处理的手段 linux内核中断机制的一个重要实现就是信号。信号使得内核和用户态的交互更加便捷,这个便捷对开发者来说可以更好的利用系统原生内核来处理信息。 《深入理解unix内核》中对信号作用的描述如下: 让进程知道已经发生了一个特定事件 强迫进程执行它自己代码中的信号处理程序 这里主要描述一下借用sigactio...

天行健,地势坤 789

LCD工程师必看:MIPI DSI的LP/HS模式切换全流程拆解(附高通平台实测)

本文为LCD工程师深度解析MIPI DSI接口中低速(LP)与高速(HS)模式切换的全流程。文章结合高通平台实测波形,从协议状态机、时序关键参数到实战调试案例,系统拆解了模式切换的本质、协同机制及常见问题排查方法,重点阐述了LP模式在低功耗控制与HS模式在高速数据传输中的核心作用与切换时序。

weixin_29240711的博客 547

告别‘线束丛林’:手把手拆解车身域控制器(BCM/PEPS/网关)的硬件选型与PCB布局要点

本文深入解析车身域控制器的硬件选型与PCB布局要点,涵盖主控MCU选择、通信接口设计、电源架构优化及EMC设计等关键环节。通过实战案例分享,帮助工程师解决高密度集成带来的电源完整性、热管理和信号隔离挑战,实现更稳定高效的汽车电子系统设计。

weixin_42567279的博客 394

linux 信号原理 信号处理设置signal, 信号发送kill,信号等待sigsuspend,信号阻塞sigprocmask,一网打尽信号使用

信号是一种软中断的方式,让进程陷入中断处理调用中;linux 下信号也是一种进程间通信的手段;进程间也可以互相发送信号,来传递状态,让对方获知,并处理一些事情。

一个追逐梦想的码农 7211

obisidian插件之【templater】模板的中文说明书

Templater 是一种模板语言,可让您将变量和函数结果插入到笔记中。它还允许您执行操作这些变量和函数的 JavaScript 代码。使用 Templater,您将能够创建强大的模板来自动执行手动任务。

m0_55795604的博客 1万+

linux信号的处理使用总结

文章链接:https://codemouse.online/archives/2020-03-23190627 发送信号 kill命令 指令格式: kill -signum pid kill 函数 int kill(pid,signum); pid>0 发给pid进程 pid=0 发给当前进程组的所有进程 pid=-1 发送给所有进程 pid<0 发送给|PID|所对应的组上 发送给自己:int kill(getpid(),signum); raise 自举函数 自举

G_Super_Mouse的博客 272

Pytorch入门实战(2)-使用BP神经网络实现MNIST手写数字识别

上一篇:Pytorch入门实战(1) - 实现线性回归 涉及知识点 Pytorch nn.Module的基本使用 Pytorch nn.Linear的基本用法 PytorchVision Transforms的基本使用 Pytorch中DataLoader的基本用法 Pytorch详解NLLLoss和CrossEntropyLoss 如何确定神经网络的层数和隐藏层神经元数量 本文内容 本文将会使用BP神经网络(就是最普通的神经网络)实现一个MNIST手写数据集的实现。话不多说,直接开始。 首先先导入需要的包

iioSnail的博客 6617

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

异步处理方式之信号(4):信号集的使用

8 信号集 8.1信号集的基本操作函数 ​ 前面我们已经知道,不同的信号的编号可能超过一个整型量所包含的位数,因此我们不能使用整型量中的一位来表示一种信号,也就是说我们不能使用整型变量来表示信号集。POSIX.1定义了一种新的数据类型:信号集(sigset_t), 并且还定义了5个处理信号的函数。 #include <signal.h> int sigemptyset(sigset...

遇见你是我最美丽的意外 4538

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

Linux下信号量的使用与处理

Linux信号量随记

Coding猿 1285

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

C++使用signal设置信号处理程序

一点睛 signal:设置信号处理方式 表头文件 #include<signal.h> 定义函数 void (*signal(int signum,void(* handler)(int)))(int); 函数说明 signal()会依参数signum 指定的信号编号来设置该信号的处理函数。当指定的信号到达时就会跳转到参数handler指定的函数执行。 如果参数...

实践求真知 2014

matlab如何进行数字信号处理,使用MATLAB进行数字信号处理-第2部分

这篇文章来源于DevicePlus.com英语网站的翻译稿。在Arduino DSP系列的第二部分中,我们将继续深入研究数字信号处理的基础知识。我们将学习数字滤波器的特性以及在MATLAB中处理信号时如何应用这些特性。在下一篇文章中,我们将制作一期有关傅里叶变换的深入教程,并研究语音信号最重要的参数:频率。软件Matlab第1步:如何将信号导入 Matlab用Audacity录制语音信号后,现在是...

weixin_39589766的博客 2407

在不同信号下使用trap处理错误

通过合理配置trap命令,您可以在Shell脚本中根据不同的信号执行不同的处理逻辑。这对于处理复杂错误场景、进行资源清理、记录日志等操作非常有用。关键点:1.捕获常见信号: 使用trap捕获SIGINTSIGTERMEXITERR等信号。2.定义处理函数: 为不同的信号定义相应的处理函数。3.组合处理逻辑: 在trap中组合多个信号和ERR,确保所有可能的异常情况都能被处理。4.清理资源: 在处理函数中执行必要的清理操作,如删除临时文件、释放锁等。

owolai的博客 1084

QTreeView使用总结5,选中信号处理

1,简介之前介绍了QTreeView的初始化和常用设置,现在数据已经显示出来了。那么QTreeView上如何处理选中、单击双击、右键菜单等操作呢?本文介绍选中信号的处理。2,选中相关信号QTreeView的选中内容由一个封装的QItemSelectionModel管理,通过QTreeView接口selectionModel()可以取得该Model指针。该Model存在这些信号:Q_SIGNALS:...

逆枫 -- C++/Qt工程师、创业者 1万+
上一篇: 定长顺序表
下一篇: 进程通讯之有名管道
IT_model
博客等级 码龄9年 61粉丝 48原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值