[a] 常用信号

  • SIGABRT  调用 abort 函数时产生此信号,进程异常终止
  • SIGALRM  调用 alarm 或 setitimer 函数超时之后产生
  • SIGCHLD  子进程终止或 stop 时内核向父进程发送此信号
  • SIGFPE  算术异常,如除以 0 或浮点溢出等
  • SIGHUP  终端连接断开时,会话首进程将收到此信号;向守护进程发送此信号使之重新读取其配置文件
  • SIGINT  中断信号,通常由 Ctrl + C 键发出,发送至前端进程组的所有进程
  • SIGQUIT  退出信号,通常由 Ctrl + \ 键发出,发送至前端进程组的所有进程
  • SIGKILL  终止进程,此信号不能被忽略或捕获
  • SIGSTOP  停止信号,不可被捕获或忽略,可通过发送 SIGCONT 继续运行
  • SIGTSTP  交互式停止信号,可继续
  • SIGCONT  使处于停止状态的进程继续运行
  • SIGTERM  退出信号,退出前进程可以做相应的清理工作
  • SIGTTIN  后端进程试图读控制终端时,终端驱动程序产生此信号,默认 stop 进程
  • SIGTTOU  后端进程试图写控制终端时,产生此信号,通常允许写出
  • SIGIO  异步 I/O 事件
  • SIGPIPE  当管道读进程已终止或 SOCK_STREAM 套接字已不再连接时,执行写操作,将收到此信号
  • SIGSEGV  无效内存引用,SEGV 代表“段违例”,即:segmentation violation
  • SIGURG  紧急情况信号,如网络连接上接到带外的数据时
  • SIGUSR1  用户自定义信号,无默认行为,用于应用程序自订信号处理机制
  • SIGUSR2  同上
  • SIGXCPU  占用 CPU 时间(秒)超过其 soft rlimit 时
  • SIGXFSZ  进程创建的文件超过所允许的软限制

[b] 关键概念

  • 低速系统调用:可能会使进程永远阻塞的系统调用继承规则:fork 出的子进程继承父进程的信号处理方式,但 exec 之后会将原捕获的信号更改为默认行为,其余不变
  • 中断的系统调用:被 sigaction 中断的调用默认不重启,可以更改其行为;被 signal 中断则默认重启,现代的 signal 函数多由 sigaction 实现
  • 可重入函数:可在信号处理进程与原进程中相互无干涉调用的函数;可重入函数可能会修改 errno 值,应在调用信号处理函数前保存 errno,在调用后恢复
  • 未决信号(pending):已产生但未递送至目标进程的信号,即被阻塞中的信号
  • 信号屏蔽字(signal mask):将被阻塞的信号集

[c] kill / raise

#include <signal.h>
int kill(pid_t pid, int signo)
int raise(int signo)
//成功返回 0,出错返回 -1 
  • raise 只能向自身发送信号,raise(signo) 等价于 kill(getpid(), signo)
  • kill 可向权限内的指定进程(signo > 0)、进程组(signo == 0 时指自身所在进程组,signo < -1 时指定其它进程组)、所有进程(signo ==  -1)发送信号

[d] sigqueue

#include <signal.h>
int sigqueue(pid_t pid, int signo, const sigval value) //成功返回 0,出错返回 -1 
  • 配合 sigaction 函数的 SA_SIGINFO 标志及 sa_sigaction 信号处理函数可实现稳健的信号排队,并附带额外的信息
  • pid 参数只能指定大于 0 的整数,value 参数用于传递额外的信息,其余行为与 kill 函数一致

[e] alarm / pause

#include <unistd.h>
unsigned int alarm(unsigned int seconds) //返回 0 或之前设置的闹钟剩余秒数
int pause(void) //返回 -1,errno 设置为 EINTR 
  • 每个进程只能有一个闹钟时间,新的闹钟将取消旧的闹钟并返回旧的闹钟剩余秒数,无旧闹钟返回 0
  • 信号处理函数必须放置在 alarm 之前
  • 只有执行了一个信号处理程序并返回后,pause 才返回,之前一直使调用进程挂起

[f] sigemptyset / sigfillset / sigaddset / sigdelset / sigismember

#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)
//成功返回 0,出错返回 -1
int sigismember(const sigset_t *set, int signo) //根据是否匹配,返回 1 或 0 
  • sigemptyset 将信号集初始化成不包含任何信号的空集
  • sigfillset 将信号集初始化成包含所有信号的全集
  • 使用任何 sigset_t 数据类型前,必须使用以上两函数之一进行初始化

[g] sigprocmask

#include <signal.h>
int sigprocmask(int how, const sigset_t *restrict set, sigset_t *restrict oldset) //成功返回 0,出错返回 -1 
  • how 参数的取值:SIG_BLOCK / SIG_UNBLOCK / SIG_SETMASK,分别代表将指定信号集 set 添加至当前屏蔽字中、从当前屏蔽字中清除 set 中的信号、将屏蔽字直接设置为信号集 set
  • 当 set 参数为 NULL 时,how 参数无意义,可以为任意值,通常设为 0
  • oldset 输出旧的信号屏蔽字

[h] sigpending

#include <signal.h>
int sigpending(sigset_t *set) //成功返回 0,出错返回 -1 
  • 将当前已被屏蔽且未决的信号写入信号集 set

[i] signal / sigaction

#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signo, sighandler_t handler); //成功返回旧的信号处理策略(指针),出错返回 SIG_ERE
int sigaction(int signo, const struct sigaction *restrict act, struct sigaction *restrict oldact) //成功返回 0,出错返回 -1 
struct sigaction {
void (*sa_handler)(int signo); //flags 中不含 SA_SIGINFO 标志时执行,否则执行 sa_sigaction 函数
sigset_t sa_mask; //信号处理函数执行过程中将被临时屏蔽/阻塞的信号
int sa_flags; //控制 sigaction 函数的行为方式
void (*sa_sigaction)(int signo, siginfo_t *info, void *context);
} struct siginfo {
int si_signo; //信号编号
int si_code; //产生信号的详细原因
...
}
  • 除自定义信号处理函数外,signal 函数中的 handler 参数可取 SIG_IGN / SIG_DFL / SIG_ERE 等三个常量,分别代表忽略信号、默认行为及 signal 进程出错
  • sigaction 结构体中 sa_flags 字段的常用取值:
    • SA_SIGINFO:此标志指示执行 sa_sigaction 信号处理函数,而不是 sa_handler,并对信号处理函数提供了附加信息
    • SA_RESTART:此标志将使被中断的系统调用在信号处理函数返回后自动重启
    • SA_NOCLDWAIT:若信号是 SIG_CHLD,则当进程的子进程终止时,不生成僵死进程,信号处理函数之后调用的 wait 类函数将一直阻塞,直到所有子进程终止,wait 返回 -1 并设置 errno 为ECHILD
  • siginfo_t 数据类型即 siginfo 结构体

[j] sigsetjmp / siglongjmp

#include <setjmp.h>
int sigsetjmp(sigjmp_buf env, int savemask) //若直接调用,返回 0;若从 siglongjmp 返回,返回 siglongjmp 的 val 参数值
int siglongjmp(sigjmp_buf env, int val) 
  • 若 savemask 非 0,则从 siglongjmp 函数跳回时,恢复原始的信号屏蔽字;其余行为与 setjmp / longjmp 函数一致
  • FreeBSD 环境下与 setjmp / longjmp 行为完全一致

[k] sigsuspend

#include <signal.h>
int sigsuspend(const sigset_t *sigmask) //返回 -1,errno 设置为 EINTR 
  • 原子操作:设置信号屏蔽字 + 挂起进程,避免了这两步之间存在时间差带来的问题
  • 直至有信号被捕获,sigsuspend 才返回,sigsuspend 返回时,将信号屏蔽字重置为之前的值

[l] abort

#include <stdlib.h>
void abort(void) //无返回值 
  • 终止进程,并产生 SIGABRT 信号
  • 功能类似于 raise(SIGABRT),但调用进程必然终止

[m] sleep / nanosleep

#include <unistd.h>
unsigned int sleep(unsigned int seconds) //返回 0,或未休眠完的秒数
#include <time.h>
int nanosleep(const struct timespec *req, struct timespec *rem) //若休眠完成,返回 0,若被中断或出错返回 -1,剩余的时间写入 rem
struct timespec {
time_t tv_sec; //秒
long tv_nsec; //纳秒
}
/*tips:类似的结构体 timeval,常见于 BSD 函数如 gettimeofday 等*/
struct timeval {
time_t tv_sec; //秒
suseconds_t tv_usec; //微秒
  • sleep 通常由 nanosleep 实现

[n] sys_siglist / strsignal

extern char *sys_siglist[]
/*数组下标是信号编号,数组中的元素是指向信号描述(字符串)的指针*/
#include <string.h>
char *strsignal(int signo) //返回指向描述该信号的字符串的指针 
  • 用于获取指定信号的字面描述

[10]APUE:信号的更多相关文章

  1. APUE学习笔记——10.9 信号发送函数kill、 raise、alarm、pause

    转载注明出处:Windeal学习笔记 kil和raise kill()用来向进程或进程组发送信号 raise()用来向自身进程发送信号. #include <signal.h> int k ...

  2. APUE信号-程序汇总

    APUE信号-程序汇总      近期重看APUE,发现对于非常多程序的要领还是没有全然理解.所以梳理下便于查看,并且有非常多值得思考的问题. 程序清单10- 1  捕获 SIGUSR1 和 SIGU ...

  3. APUE学习笔记——10.11~10.13 信号集、信号屏蔽字、未决信号

    如有转载,请注明出处:Windeal专栏 首先简述下几个概念的关系: 我们通过信号集建立信号屏蔽字,使得信号发生阻塞,被阻塞的信号即未决信号. 信号集: 信号集:其实就是一系列的信号.用sigset_ ...

  4. APUE学习笔记——10.可靠信号与不可靠信号

    首先说明:现在大部分Unix系系统如Linux都已经实现可靠信号. 1~31信号与SIGRTMIN-SIGRTMAX之间并不是可靠信号与不可靠信号的区别,在大多数系统下他们都是可靠信号. 只不过: 1 ...

  5. apue 第10章 信号signal

    每种信号都有名字,都是以SIG开头 信号机制最简单的接口是signal函数 #include <signal.h> typedef void (*sighandler_t)(int); s ...

  6. UNIX环境高级编程 第10章 信号

    SIGSTOP和SIGKILL区别是:前者是使进程暂时停止,即中止,也就是说使进程暂停,将进程挂起,比如你在终端里面执行一个脚本或者程序,执行到一半,你想暂停一下,你按下ctrl+z,就会导致终端发送 ...

  7. 《Unix环境高级编程》读书笔记 第10章-信号

    1.引言 信号是软件中断. 信号提供了一种处理异步事件的方法. 2. 信号概念 信号的名字都是以3个字符SIG开头. Linux3.2.0支持31种信号.FreeBSD.Linux和Solaris作为 ...

  8. Linux学习笔记(10)-信号

    所谓信号(singal),在我的理解来说,其实和单片机开发中的中断差不多,但是它并非是由系统硬件所提供的,而是软件操作系统的支持的一种提醒机制. 收到信号之后的处理方法,一般由三种: (1)第一种是类 ...

  9. 【linux信号】10.11信号集

    POSIX定义数据类型sigset_t以包含一个信号集,并且定义了下面五个函数处理信号集:

随机推荐

  1. EM算法(4):EM算法证明

    目录 EM算法(1):K-means 算法 EM算法(2):GMM训练算法 EM算法(3):EM算法运用 EM算法(4):EM算法证明 EM算法(4):EM算法证明 1. 概述 上一篇博客我们已经讲过 ...

  2. php的数据循环 之li的3个类判断

    这种判断必须得保证后台数据的键值为数字 ,反正要能跟数字计算的数据才行 ts2.php <?php$array = array('0'=>'a1','1'=>'b1','2'=> ...

  3. PHP开发网站之微信登录、绑定

    )))刷新access_token()); ); ); curl_setopt($curlobj, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($curlo ...

  4. (转)IC验证概述

    验证是确保设计和预定的设计期望一致的过程,设计期望通常是通过设计规范来定义的.对于芯片设计,在不同的阶段可以分为:寄存器传输级(RTL)的功能验证.门级的仿真验证.形式验证以及时序验证.我们通常所说的 ...

  5. Perl语言

    Perl是高级.通用.直译式.动态的程序语言家族.最初设计者拉里·沃尔(Larry Wall)为了让在UNIX上进行报表处理的工作变得更方便,决定开发一个通用的脚本语言,而在1987年12月18日发表 ...

  6. .net中的 InitializeComponent方法

    自己做笔记用,纯碎自己做笔记,谁看不惯想喷的请绕道 在winform开发中每一个窗体在构造函数的方法就需要 InitializeComponent方法,就是初始化 窗体组件  例如 TextBox,T ...

  7. tomcat运行时候出现java.net.BindException: Address already in use: JVM_Bind错误解决方法

    问题原因:我们在运行tomcat时候一般用8080端口,但是当端口被占用的时候便不能正常使用tomcat并且会造成上述的错误.而端口被占用的原因有很多,这次的原因是因为装好tomcat以后已经启动了一 ...

  8. javaSwing

    一.使用java Swing写个登陆界面,感受一下布局管理器的特性和熟悉一下控件的使用 package com.swing; import java.awt.BorderLayout; import ...

  9. copy(python中的引用,浅拷贝,深拷贝)

    #直接赋值 list = [1,2,['a','b'],'python'] #现将a等于list a = list print a [1,2,['a','b'],'python'] list.appe ...

  10. Android_SQLite版本升级,降级 管理

    今天我们主要学习了数据库版本升级对软件的管理操作. 我们手机经常会收到xxx软件升级什么的提醒,你的软件版本更新,同时你的数据库对应的版本也要相应的更新. 数据库版本更新需要主要的问题: 软件的1.0 ...