UNIX环境高级编程读书笔记连载之UNIX信号
时间:2010-6-9 作者:smarteng 分类: Linux命令
Unix信号真是一个有趣的东西,以前仅仅知道键入Control+C时,结束程序,但不知原理是什么,今天我就来和大家一起学习这玩意,希望大家都有收获。
所有的信号量,例如SIGINT事实上在头文件中都有定义,linux内核在Linux 2.4.22以上的,可以在/usr/include/bits/signums.h可以找到定义,看见没有,信号都是非负的整数,没啥神秘的,哈哈。
在linux终端下运行程序后,当你键入Control+C时,程序就终结了。这是因为当你键入Control+C时,相当于向当前进程发送了SIGINT信号,进程收到此信号的默认动作是立即退出。信号是异步的,进程不知道什么时候收到信号,那么产生信号的方式有那些呢?听在下慢慢道来[break]:
(1) 用户通过键盘键入信号,如Control+C代表中断SIGINT,Control+\代表退出SIGQUIT,Control+Z代表停止SIGSTOP,等等。前台进程(fore ground process)收到这些信号后,就会采取相应动作。
(2) 硬件产生信号,如除0产生SIGFPE信号,内存地址引用出错产生SIGSEGV段错误信号。
(3) Kill函数,瞧瞧它原型就知道他能干什么了,int kill(pid_t pid, int signo);可不是像它的名字一样,kill事实上不是杀死进程pid,而是向进程号为pid的进程发送信号signo,当然前提是你是这个进程的属主或是NB的超级管理员。
(4) Kill命令也能向进程发送信号,事实上,kill命令就是kill函数的包装而已,通常是用来杀掉后台进程。Man一下kill你就知道这个命令的用法了。
(5) software本身也能产生信号,如一个子进程结束时用SIGCHLD通知父进程;调用alarm()时产生的SIGALRM信号,socket套接口编程中常见的SIGPIPE信号,等等。
当信号产生时,处理的方式只有三种,忽略,默认处理或使用指定的信号安装函数。
(1) 忽略信号几乎适用于所有的信号,不过有两个信号除外,SIGKILL和SIGSTOP,要是这两个信号可以忽略,还真不知道怎么干掉后台进程,那岂不是很郁闷?试一试打开linux下的编辑工具vi,键入Control+C没有退出,而键入Control+Z时立马退出,是不是?
(2) 默认处理一般是终结进程,各种发行版本的对各个信号的默认处理有一点不同,详见APUE的10.2节。
(3) 信号安装函数是自己决定对捕获的信号如何处理,这是本章最神秘的内容,学会了这个,你就能玩明白信号编程了,需要注意的是,与忽略信号相似的是,SIGKILL和SIGSTOP信号不能被信号安装函数捕获。
各个信号的意义嘛,我就不一一介绍了,我也不大明白,只是知道几个常用的,详情请参阅APUE的10.2节。
下回预告:Signal()函数,不可靠信号,被信号中断的系统调用,可重入的函数
Unix信号量也可以在文件/usr/include/sys/signal.h中查看
#define SIGHUP 进程由於控制终端死去或者控制终端发出起命令
#define SIGINT 键盘中断所产生的信号
#define SIGQUIT 键盘终止
#define SIGILL 非法的指令
#define SIGTRAP 进程遇到一个追踪(trace)或者是一个中断嵌套
#define SIGABRT 由abort系统调用所产生的中断信号
#define SIGIOT 类似於SIGABRT
#define SIGBUS 进程试图使用不合理的记忆体
#define SIGFPE 浮点异常
#define SIGKILL KILL
#define SIGUSR1 用户自定义
#define SIGSEGV 段错误
#define SIGUSR2 用户自定义
#define SIGPIPE 管道操作时没有读只写
#define SIGALRM 由alarm系统调用产生的timer时钟信号
#define SIGTERM 收到终端信号的进程
#define SIGSTKFLT 堆叠错误
#define SIGCHLD 子进程向父进程发出的子进程已经stop或者终止的信号
#define SIGCONT 继续运行的信号
#define SIGSTOP stop
#define SIGTSTP 键盘所产生的stop信号
#define SIGTTIN 当运行在後状态时却需要读取stdin的资料
#define SIGTTOU 当运行在後状态时却需要写向stdout
#define SIGURG socket的紧急情况
#define SIGXCPU 进程超额使用CPU分配的时间
#define SIGXFSZ 进程使用了超出系统规定文件长度的文件
#define SIGVTALRM 内部的alarm时钟过期
#define SIGPROF 在一个程式段中描绘时钟集过期
#define SIGWINCH 终端视窗的改变
#define SIGIO 非同步IO
#define SIGPOLL SIGIO pollable事件发生
通过结合trap命令使用:trap <command-list> <signal-list>
以上这些Unix信号量的知识,希望大家能够记住,方便以后我们的使用。