信号
来源:互联网 发布:gps数据采集过程 编辑:程序博客网 时间:2024/04/30 04:24
前言
信号是软件中断
概念
处理方式
- 忽略 (这里有两种信号绝不能被忽略),它们是SIGKILL和SIGSTOP。不能被忽略的原因是向超级用户提供进程终止或停止的可靠方法。另外如果忽略某些硬件异常产生的信号(非常内存引用或者除以0),则进程的运行行为是未定义的。
- 捕捉 系统内核在该信号发生的时候调用用户函数来处理用户希望发生的事件处理。这里要提的是不能捕捉SIGKILL与SIGSTOP信号。
- 执行系统默认动作 大多数的系统默认动作是终止进程。“终止+core”表示从当前工作目录的core文件中复制该进程的存储映像。
信号类型
- SIGABRT 调用abort函数产生的信号。进程异常终止。
- SIGALRM alarm函数设置的计时器超时时候,产生此信号。setitimer函数也会产生此信号。
- SIGBUS 指一个实现定义的硬件故障。当出现某些类型得硬件故障时候会产生此信号。
- SIGCANCEL Solaris线程库内部使用的信号。一般应用不提供。
- SIGCHLD 一个进程终止或者停止时,将SIGCHLD信号发送给其父进程。系统默认会忽略此信号。若父进程希望被告知子进程状态改变的时候,则应该捕获此信号。
- SIGCONT 信号发送给当前停止状态的进程,让其继续运行。系统默认动作要么运行该停止进程或者忽略该信号。
- SIGEMT 指示一个实现定义的硬件故障。
- SIGFPE 算数运算异常,除以0/浮点溢出等。
- SIGFREEZE 仅Solaris定义。
- SIGILL 表示执行非法指令。
- SIGINFO 这是一种BSD状态,用户按状态键时,终端驱动将产生此信号并送至前台进程组的每一个进程。
- SIGINT 用户按中断键,终端驱动程序产生此信号发送到前台进程组的每一个进程。通常用来终止进程。
- SIGIO 指示一个异步I/O事件。
- SIGIOT 指示一个实现定义的硬件故障。
- SIGKILL 它向系统管理员提供一种可以杀死任何进行的可靠方法。不能被捕捉。
- SIGLWP 此信号Solaris线程内部使用,不用一般使用。
- SIGPOLL 在可轮训设备上发生一定特定事件时候产生此信号。
- SIGPROF 当setitimer函数设置的梗概统计间隔计时器已到期时候产生。
- SIGPWR 停机信号
- SIGQUIT 当用户在终端按退出键会产生此信号,在终止进程的同时还会产生一个core文件。
- SIGSEGV 该信号指示进程进行了一次无效内存引用。
- SIGSTKFLT 用于数学协处理器的栈故障。
- SIGSTOP 作业控制信号,用于停止一个进程。类似于交互停止信号SIGSTP。但是SIGSTOP不能被捕捉。
- SIGSYS 该信号只是一个无效的系统调用。
- SIGTERM 由kill命令发送的系统默认终止信号。
- SIGTHAW Solaris专属。当系统恢复运行的时候,该信号用来通知相关进程让其采取特定动作。
- SIGTRAP 指示一个实现的硬件故障。
- SIGTSTP 交互式停止信号,用户在终端按挂起键的时候,终端驱动产生此信号。该信号送至前台进程组中的所有进程。
- SIGTTIN 当一个后台进程组的进程试图读其控制终端时,终端驱动产生此信号。
- SIGTTOU 当一个后台进程组的进程试图写其控制终端时,终端驱动产生此信号。
- SIGURG 此信号通知进程已经发生一个紧急情况。网络收到数据可以使用此信号。
- SIGUSR1 用户定义的信号,可适用于应用。
- SIGUSR2 同上
- SIGVTALRM 当一个由setitimer函数设置的虚拟间隔时间到期的时候产生此信号。
- SIGWAITTING Solaris线程库专属。
- SIGWINCH 内核维持与每个终端或者伪终端相关联得窗口大小。
- SIGXCPU 如果进程超过了软CPU时间限制,则产生该信号。
- SIGXFSZ 如果进程超过了其软文间长度限制,则缠身该信号。
- SIGXERS Solaris专属。通知进程超过了预配置资源。
信号函数
#include <signal.h>void (*signal(int signo, void (*func)(int)))(int);
singno
是上述中的信号名,是一个signo整数。func
函数指针,指向的函数带一个整型参数,无返回值。其值是常量SIG_IGN、SIG_DFL或者接到此信号要调用的函数地址。指定SIG_IGN则表示忽略该信号。如果指定SIG_DFL则表示是系统执行默认动作。当是指定函数地址的时候则是“捕捉”该信号。我们称这个函数为信号处理句柄(signal handler)或者信号捕捉函数。signal
返回的是一个函数地址,该函数有一个整型参数。
为了简化模型同时便于理解引用typedef
。
typedef void Sigfunc(int);Sigfunc *signal(int , Sigfunc *);
举个捕捉SIGUSR1和SIGUSR2的栗子:
#include <signal.h>#include <apue.h>void (*signal(int signo, void (*func)(int)))(int);typedef void Sigfunc(int);Sigfunc *signal(int , Sigfunc *);static void sig_usr(int);int main (void) { if (signal(SIGUSR1, sig_usr) == SIG_ERR) { err_sys("can't catch SIGUSR1"); } if (signal(SIGUSR2, sig_usr) == SIG_ERR) { err_sys("can't catch SIGUSR2"); } for (; ;) { pause(); }}static void sig_usr(int signo) { if (signo == SIGUSR1) { printf("received SIGUSR1\n"); } else if (signo == SIGUSR2) { printf("received SIGUSR2\n"); } else { err_dump("received signal %d\n", signo); }}
0 0