基于 linux的 信号详解

1、信号:

每个信号都一个一个名字,都已SIG开头;不存在编号为0的信号;

2、产生信号的条件:

a、用户使用了终端按键;

b、硬件异常(如除0,无效的内存引用);

c、进程调用kill(2)函数,将信号发送给另一个进程;(注意,另一进程必须和发送进程的的所有者必须相同,或者发送信号的所有者必须是超级用户);

d、当检查到某种软件条件已经发生时,将其通知相关进程时,也产生信号;

3、信号是异步事件的经典;信号的产生是随机的,进程不能通过测试一个变量来测试是否出现了信号,而是必须告诉内核,在该信号出现时,请执行下列操作;

4、内核对出现的信号可有三种动作可选:

a、忽略此信号(注意:SIGKILL 信号 和 SIGSTOP信号,不可被忽略);

b、捕捉信号;简单来说,就是抓到该信号后,执行进程提供给内核的处理函数;注意,SIGKILL和SIGSTOP不可被捕获;

c、执行默认动作;每种信号都有默认动作,大多数信号的默认动作是终止进程;

5、常见信号解释:

a、SIGCHLD     在一个进程终止时,将SIGCHLD信号发送给其父进程;

b、SIGFPE        算数异常;

c、SIGPIPE       写管道,但是管道的读端已经终止,会产生此信号;

d、SIGPWR      不间断电源(UPS)失效;

e、SIGSEGV     无效的内存引用;

f、 SIGSTOP     终止进程;

g、SIGSYS       无效的系统调用;

h、SIGTERM     由kill(1)命令发送的终止信号;

i、 SIGXFSZ      进程超过了其软文件长度的限制;

6、信号处理函数:

Sigfunc *signal(int,  Sigfunc*);

参数1:信号宏;

参数2:处理函数;

特殊情况:有几个默认的函数宏,用户默认,忽略,错误处理;

#define SIG_ERR   (void (*)()) -1;

#define SIG_DFL   (void (*)()) 0;

#define SIG_IGN   (void (*)()) 1;

返回值:函数指针;

7、kill(1)  命令和kill(2)函数只是将一个信号送给一个进程或者进程组,信号是否终止,取决于信号的类型,以及进程是否安排了捕捉该信号;

8、当一个进程用fork时,其子进程继承父进程的信号处理方式;

9、  pause函数;

#include <unistd.h>

int pause(void);

该函数,是本进程挂起,指导捕捉到一个信号;只有执行了信号处理函数,并从其中返回时,pause才会返回;在这种情况下,返回是-1;并将error设置为EINTR;

pause函数,使自己休眠,直到捕捉到一个信号;

10、当捕捉到某个信号是,被中断的是内核中执行的系统调用;

12、不可重入函数的原因:

a、该函数使用了静态数据结构;

b、调用了malloc或者free;

c、使用了表中I/O函数,因为表中I/O函数,很多实现都使用了全局的数据结构;

13、在信号产生和信号递达的间隔内,信号处于未决状态;

14、每个信号都有一个信号屏蔽字,该信号屏蔽字规定了要阻塞送到该进程的的信号集。当某个信号递送时即将到达时,发现对应位被设置,则他当前是被阻塞的;

15、kill函数:

#include<signal.h>

int kill(pid_t pid, int signo);

作用:将信号发送给某个进程或者进程组;

参数1: pid > 0,表示将该信号发送给ID 为pid的进程;

pid == 0 ; 将进程发送给本组所有进程;

pid < 0 ,将信号发送给进程组ID 等于 pid绝对值的组;

pid == -1; 表示该进程把信号发送给 “所有自己有权发送给”的那些进程;

16、将编号为0 的信号定义为空信号,使用kill时,signo为0 ,可以进行错误检查,但是不发任何信号,这常被用来测试一个进程是否存在,如果不存在,则返回-1;并将error置为ESRCH;

17、raise函数;

int raise(int signo)函数,用于向进程自身发送信号;

18、alarm函数:

#include <unistd.h>

unsigned int alarm(unsigned int seconds);

使用该函数,设定一个定时器,定时器过期时,会产生SIGALRM信号,该信号的默认动作是终止进程;

每个进程同时只能有一个alarm,否则,新使用的alarm会替代旧的alarm,新alarm 会将旧alarm所剩余的时间返回;

将seconds可以取消以前的闹钟,返回余留值;

注意:如果要使用alarm函数,且在在捕捉到SIGALRM信号后,要做相应的处理,则应该在调用alarm函数之前,设置该信号的处理函数;

19、信号集:

信号集:告诉内核不允许发生该信号集中的信号;

五个基本的信号集操作函数:

#include <signal.h>

int sigemptyset(sigset_t *set);

信号集置空;

int sigfillset(sigset_t *set);

信号集置满;

int sigaddset(sigset_t *set, int signo);

增加信号;

int sigdelset(sigset_t *set, int signo);

删除信号;

int sigismember(const sigset_t *set, int signo);

判断signo是否是信号集成员;

20、sigprocmask函数

#include<signal.h>

int sigprocmask(int how, const sigset_t *restrict set, sigset_t *restrict oset);

成功则返回0,出错返回-1;

当oset 为非空指针时,进程的当前信号屏蔽字通过oset返回;

当set不是空指针时,how用来说明修改当前信号屏蔽字的方式,修改方式包括:SIG_BLOCK(set 和 oset的并集);SIG_UNBLOCK(oset与 “set 信号集的补集“的交集)

SIG_SETMASK(指定用set替代旧的信号集);

21、 sigpending 函数:

用于返回被阻塞而不能递送的信号集;

22、sigaction函数;

功能是检查或者修改与指定信号的相关联的处理动作;与signal作用类似;

#include <signal.h>

int sigaction(int signo, const struct sigaction *restrict act, struct sigaction *restrict oact);

返回值:成功则返回0, 出错返回-1;

signo : 表示要检查或者修改具体动作相关联的某个信号;

struct sigaction 结构体:

struct sigaction{

void  (*sa_handler)(int) ;            //与信号相关的处理函数或者SIG_IGN,SIG_DEF;

sigset_t sa_mask;                      //信号集;在调用该函数之前,首先应该用此设置信号集;

int sa_flags;                               //包含对信号处理的各个选项;

void  (*sa_sigaction)(int, siginfo_t *, void *);   当在flag中使用了SA_SIGINFO标志时,使用此处理程序;(注意,此函数指针和第一个处理信号的函数指针,两者只能使用其中之一;)zaisiginfo_t结构体中包含了信号产生原因的相关信息;

时间: 2024-10-11 21:25:11

基于 linux的 信号详解的相关文章

Linux信号详解

Linux信号详解 一 信号的种类 可靠信号与不可靠信号, 实时信号与非实时信号 可靠信号就是实时信号, 那些从UNIX系统继承过来的信号都是非可靠信号, 表现在信号 不支持排队,信号可能会丢失, 比如发送多次相同的信号, 进程只能收到一次. 信号值小于 SIGRTMIN的都是非可靠信号. 非可靠信号就是非实时信号, 后来, Linux改进了信号机制, 增加了32种新的信号, 这些信 号都是可靠信号, 表现在信号支持排队, 不会丢失, 发多少次, 就可以收到多少次. 信号值 位于 [SIGRTM

linux系统下信号详解2

信号是UNIX 系统所使用的进程通信方法中,最古老的一种.信号不但能从内核发往一个进程,也能从一个进程发往另一个进程.例如,用户在后台启动了一个要运行较长时间的程序,如果想中断其执行,可以用kill 命令把SIGTERM信号发送给这个进程,SIGTERM 将终止此进程的执行.信号还提供了向UNIX 系统进程传送软中断的简单方法.信号可以中断一个进程,而不管它正在作什么工作.由于信号的特点,所以不用它来作进程间的直接数据传送,而把它用作对非正常情况的处理.由于信号本身不能直接携带信息,这就限制了它

红帽Linux故障定位技术详解与实例(1)

红帽Linux故障定位技术详解与实例(1) 2011-09-28 14:26 圈儿 BEAREYES.COM 我要评论(0) 字号:T | T 在线故障定位就是在故障发生时, 故障所处的操作系统环境仍然可以访问,故障处理人员可通过console, ssh等方式登录到操作系统上,在shell上执行各种操作命令或测试程序的方式对故障环境进行观察,分析,测试,以定位出故障发生的原因. AD:2014WOT全球软件技术峰会北京站 课程视频发布 红帽Linux故障定位技术详解与实例是本文要介绍的内容,主要

Linux系统启动过程详解

 Linux系统启动过程详解 启动第一步--加载BIOS当你打开计算机电源,计算机会首先加载BIOS信息,BIOS信息是如此的重要,以至于计算机必须在最开始就找到它.这是因为BIOS中包含了CPU的相关信息.设备启动顺序信息.硬盘信息.内存信息.时钟信息.PnP特性等等.在此之后,计算机心里就有谱了,知道应该去读取哪个硬件设备了. 启动第二步--读取MBR众所周知,硬盘上第0磁道第一个扇区被称为MBR,也就是Master Boot Record,即主引导记录,它的大小是512字节,别看地方不大,

linux之LVM详解

Linux的LVM详解 LVM组成; LVM:logic volume manager .LVM即逻辑卷管理,现在使用版本为第二版,即version2 逻辑卷:pv,physical volume,即计算机上的磁盘设备,例如我的计算机上的/dev/sda3,/dev/sda5. 卷组:vg,volume group.一般由多个pv组成. 逻辑卷:lv,logical volume是在vg上是划分好可以直接使用分区 pe:physical extend,是在pv加入vg后vg把所有pv划分成的很多

linux设备号详解

原文:http://blog.csdn.net/zjjyliuweijie/article/details/7001383 linux 中的设备有2种类型:字符设备(无缓冲且只能顺序存取).块设备(有缓冲且可以随机存取).每个字符设备和块设备都必须有主.次设备号,主设备号相同的设 备是同类设备(使用同一个驱动程序).这些设备中,有些设备是对实际存在的物理硬件的抽象,而有些设备则是内核自身提供的功能(不依赖于特定的物理硬件,又称为"虚拟设备").每个设备在 /dev 目录下都有一个对应的

Linux串口编程详解

串口本身,标准和硬件 ? 串口是计算机上的串行通讯的物理接口.计算机历史上,串口曾经被广泛用于连接计算机和终端设备和各种外部设备.虽然以太网接口和USB接口也是以一个串行流进行数据传送的,但是串口连接通常特指那些与RS-232标准兼容的硬件或者调制解调器的接口.虽然现在在很多个人计算机上,原来用以连接外部设备的串口已经广泛的被USB和Firewire替代:而原来用以连接网络的串口则被以太网替代,还有用以连接终端的串口设备则已经被MDA或者VGA取而代之.但是,一方面因为串口本身造价便宜技术成熟,

linux curl用法详解

linux ‍‍curl用法详解 ‍‍curl的应用方式,一是可以直接通过命令行工具,另一种是利用libcurl库做上层的开发.本篇主要总结一下命令行工具的http相关的应用, 尤其是http下载方面的:下一篇再讲基于libcurl库的开发. curl的命令行工具功能非常强大,这些数据交互的功能基本上都是通过URL方式进行的,我们先来看看curl对多个URL的灵活操作,这些规则使我们的 批处理需求应用起来非常方便. 1.用{}表示多个URL    如 http://site.{one,two,t

linux find命令详解--转

转自:http://blog.csdn.net/jakee304/article/details/1792830 (一)Get Start 最简单的find用法莫过于如此: $ find . 查找当前目录下的所有文件.find命令的一般格式为: find [-H] [-L] [-P] [path...] [expression] 其中,'-H' '-L' '-P'三个选项主要是用来处理符号连接,'-H'表示只跟随命令行中指定的符号连接,'-L'表示跟随所有的符号连接,'-P'是默认的选项,表示不