Linux信号之signal函数

1. 信号概述
何为信号:信号就是由用户、系统或进程发送给目标进程的信息,以通知目标进程中某个状态的改变或是异常。
信号产生:总体来说,其产生的条件有两种,分别是:硬件和软件原因,又称为:硬中断和软中断。可细分为如下几种原因:
①系统终端Terminal中输入特殊的字符来产生一个信号,比如按下:ctrl+\会产生SIGQUIT信号。
②系统异常。比如访问非法内存和浮点数异常。
③系统状态变化。如设置了alarm定时器,当该定时器到期时候会引起SIGVTALRM信号。
④调用了kill命令或是kill函数。
 

 

1. 1 系统如何处理信号
Linux系统对于接收到的信号(无论是硬中断还是软中断)可以有三种处理方式:
(1)忽略此信号。SIG_IGN,该常数表示信号函数的忽略。在/usr/include/x86_64-linux-gnu/bits/signum.h
头文件中有SIG_IGN的宏定义
 

#define SIG_IGN	((__sighandler_t) 1) /* 忽略信号  */

(2)执行系统默认的动作。SIG_DFL,该常数表示信号的默认值。对于大多数的系统来说,系统的默认动作就是终止该进程。在/usr/include/x86_64-linux-gnu/bits/signum.h
头文件中有SIG_IGN的宏定义

#define SIG_DFL	((__sighandler_t) 0)  /* 默认动作  */

 值得注意的是:Linux下的系统默认动作一般有如下几种:
①结束进程(Term)
②忽略信号(Ignore)
③结束进程并生成核心转储文件(Core),该文件用于gdb后期调试
④暂停进程(Stop)
⑤继续进程(Continue),如果进程被挂起,则恢复进程的运行。否则,忽略该信号。
(3)捕捉该信号。这里需要用户自定义一个函数,来对产生的信号进行捕捉,而在这个函数中可执行用户希望对这个事件进行的处理操作。
 

2. 使用signal函数捕捉信号
在处理由系统产生的一个信号时候,首先得对产生的该信号进行安装登记,这样才能对其进行处理。何为安装登记呢?其实很好理解,好比你去图书馆借阅图书,当你找到了喜欢的书籍后,再用借书卡去机器上面扫描登记,然后就可以带走该书籍去阅读了。这里的图书相当于信号,用借书卡登记和对信号进行登记同个道理,处理信号相当于你将书籍带离图书馆阅读。Linux上有两个函数都可用来对信号进行登记,分别是:signal和 sigaction 。
这两个函数的区别:
(1)signal是在系统调用的基础上实现,是库函数,它有两个参数,不支持信号传递信息,主要用于kill -l 中的前32个非实时信号的安装。
(2)sigaction是较新的函数,(由sys_signal和sys_rt_sigaction两个系统调用实现 ),有3个参数。支持信号传递信息,主要用来和sigqueue系统调用配合使用。
 

2.1 signal详解

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

- 函数说明:设置信号处理方式。signal()会依参数signum指定的信号编号(0~64)来设置该信号 的处理函数。当指定的信号到底时,就会跳转到参数handler指定的函数执行。

signal函数成功时返回一个函数指针,该函数指针的类似也是sighandler_t。返回值是前一次调用signal函数时传入的函数指针,或者是信号signum对应的默认处理函数指针SIG_DFL(如果是第一次调用的话)
signal系统调用出错时返回SIG_ERR并设置errno。
 

#define SIG_ERR	((__sighandler_t) -1)		/* 错误返回  */

 代码1

/************************************************************************** File Name: signal.cpp* Author:    The answer* Function:  Other        * Mail:      2412799512@qq.com * Created Time: 2018年05月13日 星期四 18时47分11秒************************************************************************/#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
using namespace std;void sig_handler(int signum)
{if(0 > signum){fprintf(stderr,"sig_handler param err. [%d]\n",signum);return;}if(SIGINT == signum){printf("Received signal [%s]\n",SIGINT==signum?"SIGINT":"Other");}if(SIGQUIT == signum){printf("Received signal [%s]\n",SIGQUIT==signum?"SIGQUIT":"Other");}return;
}int main(int argc,char **argv)
{printf("Wait for the signal to arrive.\n ");/*登记信息*/signal(SIGINT,sig_handler);signal(SIGQUIT,sig_handler);pause();pause();signal(SIGINT,SIG_IGN);return 0;
}

程序运行后会一直等待用户的输入,当在终端按下ctrl+c时候会打印^C Received signal [SIGINT]
说明捕获到了SIGINT信号,接着程序继续等待,当按下ctrl+\时候会打印^\Received signal [SIGQUIT]
表明捕获到了SIGQUIT信号,如下图所示:

在Linux的目录/usr/include/x86_64-linux-gnu/bits/signum.h下有对所有信号的宏定义,所以可以用来和int值进行比较。

3. Linux标准信号

在Linux终端下 kill -l 可以查看所有的信号。

这里是上面64种信号的说明:

信号    起源    默认行为    含义
SIGHUP    POSIX    Term    控制终端挂起
SIGINT    ANSI    Term    键盘输入以终端进程(ctrl + C)
SIGQUIT    POSIX    Core    键盘输入使进程退出(Ctrl + \)
SIGILL    ANSI    Core    非法指令
SIGTRAP    POSIX    Core    断点陷阱,用于调试
SIGABRT    ANSI    Core    进程调用abort函数时生成该信号
SIGIOT    4.2BSD    Core    和SIGABRT相同
SIGBUS    4.2BSD    Core    总线错误,错误内存访问
SIGFPE    ANSI    Core    浮点异常
SIGKILL    POSIX    Term    终止一个进程。该信号不可被捕获或被忽略
SIGUSR1    POSIX    Term    用户自定义信号之一
SIGSEGV    ANSI    Core    非法内存段使用
SIGUSR2    POSIX    Term    用户自定义信号二
SIGPIPE    POSIX    Term    往读端关闭的管道或socket链接中写数据
SIGALRM    POSIX    Term    由alarm或settimer设置的实时闹钟超时引起
SIGTERM    ANSI    Term    终止进程。kill命令默认发生的信号就是SIGTERM
SIGSTKFLT    Linux    Term    早期的Linux使用该信号来报告数学协处理器栈错误
SIGCLD    System V    Ign    和SIGCHLD相同
SIGCHLD    POSIX    Ign    子进程状态发生变化(退出或暂停)
SIGCONT    POSIX    Cont    启动被暂停的进程(Ctrl+Q)。如果目标进程未处于暂停状态,则信号被忽略
SIGSTOP    POSIX    Stop    暂停进程(Ctrl+S)。该信号不可被捕捉或被忽略
SIGTSTP    POSIX    Stop    挂起进程(Ctrl+Z)
SIGTTIN    POSIX    Stop    后台进程试图从终端读取输入
SIGTTOU    POSIX    Stop    后台进程试图往终端输出内容
SIGURG    4.3 BSD    Ign    socket连接上接收到紧急数据
SIGXCPU    4.2 BSD    Core    进程的CPU使用时间超过其软限制
SIGXFSZ    4.2 BSD    Core    文件尺寸超过其软限制
SIGVTALRM    4.2 BSD    Term    与SIGALRM类似,不过它只统计本进程用户空间代码的运行时间
SIGPROF    4.2 BSD    Term    与SIGALRM 类似,它同时统计用户代码和内核的运行时间
SIGWINCH    4.3 BSD    Ign    终端窗口大小发生变化
SIGPOLL    System V    Term    与SIGIO类似
SIGIO    4.2 BSD    Term    IO就绪,比如socket上发生可读、可写事件。因为TCP服务器可触发SIGIO的条件很多,故而SIGIO无法在TCP服务器中用。SIGIO信号可用在UDP服务器中,但也很少见
SIGPWR    System V    Term    对于UPS的系统,当电池电量过低时,SIGPWR信号被触发
SIGSYS    POSIX    Core    非法系统调用
SIGUNUSED        Core    保留,通常和SIGSYS效果相同
 

原文地址:https://blog.csdn.net/lixiaogang_theanswer/article/details/80301624

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

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

相关文章

Linux中wait()函数及waitpid()函数

编程过程中&#xff0c;有时需要让一个进程等待另一个进程&#xff0c;最常见的是父进程等待自己的子进程&#xff0c;或者父进程回收自己的子进程资源包括僵尸进程。这里简单介绍一下系统调用函数&#xff1a;wait() 函数原型是 #include <sys/types.h> #include <…

学习笔记 --- DM9000网卡原理与基地址设置

前面有文章分析了网卡也是属于类内存总线的设备&#xff0c;类内存总线的设备有地址总线和数据总线&#xff0c;先来看下DM9000的管脚&#xff1a; 从上面可以看出DM9000的地址总线就一根&#xff0c;它不像CS8900那样地址总线和数据总线都齐全。而这里只有一根地址线(CMD)&…

静态VLAN的配置

在一台交换机上连接3台PC机&#xff0c;然后创建两个VLAN&#xff0c;分别为VLAN 10 和VLAN 20&#xff0c;把第一台PC机分配给VLAN 10&#xff0c;把其他两台分配给VLAN 20.然后测试他们的互通情况。 在这里命令我用的都是简化命令&#xff0c;想卡完整版命令&#xff0c;请到…

静态路由原理

1、路由器的工作原理 路由工作简单原理图 1&#xff09;主机1.1要发生数据包给主机4.1.因为IP地址不在同一网段&#xff0c;所以主机会将数据包发送给本网段的网关路由器。 2&#xff09;路由器A 接收到数据包&#xff0c;先查看数据包IP首部中的目标IP地址。再查找自己的路由表…

静态路由和默认路由

一、静态路由的配置 下边实验对该拓扑图进行配置 实验目标&#xff1a;配置静态路由&#xff0c;实现全网互通 1、配置路由器R1 进入接口f0/0&#xff0c;配置IP&#xff0c;并开启。 进入接口f0/1&#xff0c;配置IP&#xff0c;并开启。 设置静态路由。 查看PC1的路由表 2、配…

IP地址192.168.1.1/24中的/24是什么意思

/24是指子网掩码的位数。 子网掩码的位数总共有32个&#xff0c;写的的/24个就是24个1&#xff0c;其它8位都是0。 /24就可以写成子网掩码是&#xff1a;11111111 11111111 11111111 00000000 例如&#xff1a; /25&#xff0c;就代表有25个1&#xff0c;7个0&#xff0c;…

IP地址中A类、B类、C类地址的区别

区别如下&#xff1a; 1、IP地址表示方法不同&#xff1a; 一个A类IP地址是指&#xff0c; 在IP地址的四段号码中&#xff0c;第一段号码为网络号码&#xff0c;剩下的三段号码为本地计算机的号码。如果用二进制表示IP地址的话&#xff0c;A类IP地址就由1字节的网络地址和3字…

原始套接字简介

一 原始套接字概述 原始套接字&#xff0c;指在传输层下面使用的套接字。流式套接字和数据报套接字这两种套接字工作在传输层&#xff0c;主要为应用层的应用程序提供服务&#xff0c;并且在接收和发送时只能操作数据部分&#xff0c;而不能对IP首部或TCP和UDP首部进行操作&am…

TCP socket心跳包示例程序

TCP socket心跳包示例程序_xqhrs232的专栏-CSDN博客_setsockopt 心跳包 原文地址::TCP socket心跳包示例程序_神奕的专栏-CSDN博客_tcp心跳包 相关文章 1、Linux网络编程--服务端判断客户端断开的经验方法 ----Linux网络编程--服务端判断客户端断开的经验方法_志存高远-CSDN博…

sizeof()计算结构体的大小

原文链接&#xff1a;sizeof()计算结构体的大小_海月汐辰-CSDN博客_结构体的sizeof怎么计算 简要说明&#xff1a;结构体成员按照定义时的顺序依次存储在连续的内存空间&#xff0c;但是结构体的大小并不是简单的把所有成员大小相加&#xff0c;而是遵循一定的规则&#xff0c…

select、poll、epoll使用小结

转载&#xff1a;http://blog.csdn.net/kkxgx/article/details/7717125 Linux上可以使用不同的I/O模型&#xff0c;我们可以通过下图了解常用的I/O模型&#xff1a;同步和异步模型&#xff0c;以及阻塞和非阻塞模型&#xff0c;本文主要分析其中的异步阻塞模型。 一、select使用…

Qt报错:undefined reference to xxxxx

报错信息&#xff1a; 首先&#xff0c;要区分与undefined reference to xxxxx和 "xxxx was not declared in this scope"两种报错信息的差别&#xff0c;前者是因为编译器能找到函数的声明&#xff0c;但是找不到函数的定义&#xff0c;从而报错&#xff1b;而后者是…

对象的浅拷贝和深拷贝

对象的浅拷贝和深拷贝简要介绍代码实现简要介绍 浅拷贝&#xff1a;python拷贝一般都是浅拷贝。拷贝时&#xff0c;对象包含的子对象内容不拷贝。因此&#xff0c;源对象和拷贝对象引用同一个对象 深拷贝&#xff1a;使用copy模块的deepcopy函数&#xff0c;递归拷贝对象中包含…

用模板写单链表

转载自&#xff1a;http://blog.csdn.net/itcastcpp/article/details/39081953 为了加深对模板的理解&#xff0c;我们今天一起用模板写一个单链表&#xff0c;希望通过这个例子&#xff0c;能够帮助大家加深对模板的体会&#xff0c;具体如下&#xff1a; SList.hpp内容&#…

QT事件事件之一:Qt中的事件处理与传递

QT事件事件之一&#xff1a;Qt中的事件处理与传递前言一、简介二、QT中的事件三、事件的实现的方法前言 在QT中&#xff0c;事件是我们很常用的东西&#xff0c;以下是我用事件时总结和做法 一、简介 在QT中&#xff0c;事件作为一个对象&#xff0c;继承QEvent类&#xff0c…

linux下成功安装ffmpeg( 亲测有效 )

linux下成功安装ffmpeg&#xff08; 亲测有效 &#xff09;一、下载二、安装步骤1.安装yasm2.安装ffmpeg总结一、下载 ffmpeg 官网下载&#xff1a; http://ffmpeg.org/download.html 安装yasm 官网下载&#xff1a;http://yasm.tortall.net/Download.html 二、安装步骤 1.…

C++实现 简单 单链表

转自&#xff1a; http://blog.csdn.net/wonggonghong/article/details/21527577 我们首先建立一个<List.h>头文件&#xff0c;声明一个单链表结构&#xff1a; #include "List.h" [cpp] view plaincopy //创建一个单链表结构&#xff0c;包含一些常见的操作 …

ffmpeg音视频基础知识

ffmpeg音视频基础知识前言一、图像的基础知识二、视频编码基础知识1.视频和图片之间的关系2.为什么要编码&#xff1f;3.什么是编码&#xff1f;视频相关专业术语提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言…

Linux系统编程(一)

Linux系统编程&#xff08;一&#xff09;一、进程和程序二、内存布局内核空间用户空间三、进程状态四、环境变量五、进程共享一、进程和程序 程序&#xff1a;是指编译好的二进制文件&#xff0c;存储在磁盘中&#xff0c;不占用系统资源。 进程&#xff1a;是系统进行资源分…

Linux的SOCKET编程 简单演示

转载&#xff1a;http://blog.csdn.net/hguisu/article/details/7445768/ Linux的SOCKET编程详解 1. 网络中进程之间如何通信 进 程通信的概念最初来源于单机系统。由于每个进程都在自己的地址范围内运行&#xff0c;为保证两个相互通信的进 程之间既互不干扰又协调一致工作&a…