UNIX环境高级编程读书笔记连载之UNIX信号

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信号量的知识,希望大家能够记住,方便以后我们的使用。


smarteng 发布于 2010-06-09 19:43