UNIX.signal
来源:互联网 发布:卖数据 编辑:程序博客网 时间:2024/05/17 03:04
UNIX.signal
10 Signals
1 Introduction & Concepts
Signals是一种软件中断,通知程序某种事件的发生。常见的Signal有SIGABRT(当进程调用abort函数的时候自动发送), SIGALRM(当timer被触发的时候自动发送),等等。
下面的情况可以产生Signal:
1.
2.
3.
4.
5.
当Signal发生的时候,可以有三种选择(称之为Disposition of the signal或者Action associated with a signal)
1.
2.
3.
部分Signal的缺省行为不仅中止进程,同时还会产生core dump,也就是生成一个名为core的文件,其中保存了退出时进程内存的镜像,可以用来调试。在下面情况,不会生成core文件:
1.
2.
3.
4.
5.
2 Signals
Signal
Description
SIGABRT
由调用abort函数产生,进程非正常退出
SIGALRM
用alarm函数设置的timer超时或setitimer函数设置的interval timer超时
SIGBUS
某种特定的硬件异常,通常由内存访问引起
SIGCANCEL
由Solaris Thread Library内部使用,通常不会使用
SIGCHLD
进程Terminate或Stop的时候,SIGCHLD会发送给它的父进程。缺省情况下该Signal会被忽略
SIGCONT
当被stop的进程恢复运行的时候,自动发送
SIGEMT
和实现相关的硬件异常
SIGFPE
数学相关的异常,如被0除,浮点溢出,等等
SIGFREEZE
Solaris专用,Hiberate或者Suspended时候发送
SIGHUP
发送给具有Terminal的Controlling Process,当terminal被disconnect时候发送
SIGILL
非法指令异常
SIGINFO
BSD signal。由Status Key产生,通常是CTRL+T。发送给所有Foreground Group的进程
SIGINT
由Interrupt Key产生,通常是CTRL+C或者DELETE。发送给所有ForeGround Group的进程
SIGIO
异步IO事件
SIGIOT
实现相关的硬件异常,一般对应SIGABRT
SIGKILL
无法处理和忽略。中止某个进程
SIGLWP
由Solaris Thread Libray内部使用
SIGPIPE
在reader中止之后写Pipe的时候发送
SIGPOLL
当某个事件发送给Pollable Device的时候发送
SIGPROF
Setitimer指定的Profiling Interval Timer所产生
SIGPWR
和系统相关。和UPS相关。
SIGQUIT
输入Quit Key的时候(CTRL+\)发送给所有Foreground Group的进程
SIGSEGV
非法内存访问
SIGSTKFLT
Linux专用,数学协处理器的栈异常
SIGSTOP
中止进程。无法处理和忽略。
SIGSYS
非法系统调用
SIGTERM
请求中止进程,kill命令缺省发送
SIGTHAW
Solaris专用,从Suspend恢复时候发送
SIGTRAP
实现相关的硬件异常。一般是调试异常
SIGTSTP
Suspend Key,一般是Ctrl+Z。发送给所有Foreground Group的进程
SIGTTIN
当Background Group的进程尝试读取Terminal的时候发送
SIGTTOU
当Background Group的进程尝试写Terminal的时候发送
SIGURG
当out-of-band data接收的时候可能发送
SIGUSR1
用户自定义signal 1
SIGUSR2
用户自定义signal 2
SIGVTALRM
setitimer函数设置的Virtual Interval Timer超时的时候
SIGWAITING
Solaris Thread Library内部实现专用
SIGWINCH
当Terminal的窗口大小改变的时候,发送给Foreground Group的所有进程
SIGXCPU
当CPU时间限制超时的时候
SIGXFSZ
进程超过文件大小限制
SIGXRES
Solaris专用,进程超过资源限制的时候发送
3 Signal Function
#include <signal.h>
Void (*signal(int signo, void (*func)(int)))(int);
返回之前的signal处理函数,错误返回SIG_ERR
1.
2.
如果用exec创建子进程,那么子进程的所有Signal状态是缺省或者忽略:
1.
2.
如果用fork创建子进程,那么子进程会继承所有父进程的Signal状态。
4 Unreliable Signals
早期的UNIX系统的Signal是不稳定的:
1.
2.
3.
5 Interrupted System Calls
1.
2.
3.
4.
5.
6 Reentrant Functions
在Signal处理函数中,有可能在执行某个函数的时候,signal产生并调用了signal处理函数,然后再signal处理函数中再次调用了此函数,如果此函数调用了malloc/free,或者使用了static变量等技巧,会造成此函数不可再次被调用,此函数就是不可重入,反之就是可以重入的。UNIX标准定义了一个表,表中的函数都是可重入的。
7 Reliable Signal Terminology and Semantics
1.
2.
a.
b.
3.
4.
5.
8 kill and raise Functions
Kill函数对某个进程发送signal,而raise对本进程发送signal:
#include <signal.h>
int kill(pit_t pid, int signo);
int raise(int signo)
成功返回0,错误返回-1
对于pid可以有4种可能性:
1.
2.
3.
4.
顺便说一句,我认为这个design不太好,最好设计成四个不同函数。
Superuser可以发送signal给任何进程,而对于一般用户来说,发送者的user id必须等于接收者的user id
如果signo=0,则是告诉kill函数检查该进程是否存在。如果不存在,则返回错误-1,errno设置为ESRCH。
9 alarm and pause Functions
Alarm函数设置一个timer,到固定时间之后会expire,发送一个SIGALRM signal:
#include <signal.h>
unsigned int alarm(unsigned int second);
返回前一个alarm的剩余时间值,单位为秒
SIGALRM的缺省行为是中止进程。同一个进程只能有一个alarm。调用alarm函数会取消前一个alarm,并返回前一个alarm的剩余时间。如果second值为0,则只是取消前一个alarm。
Pause函数暂停当前进程的运行,直到某个signal被catch:
#include <signal.h>
int pause(void);
总是返回-1,errno总是设置为EINTR
10 signal sets
多个signal的集合用signal set表示,类型为sigset_t,下面函数用于操作sigset_t:
#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(sigset_t *set, int signo);
返回1如果是,不是则返回0
1.
2.
3.
4.
11 sigprocmask Function
sigprocmask函数设置进程的signal mask,可以block/unblock signal:
#include <signal.h>
int sigprocmask(int how, const sigset_t *restrict set, sig_set *restrict oset);
成功返回0,错误返回-1
1.
How
Description
SIG_BLOCK
在原来的mask基础上Block signal set
SIG_UNBLOCK
在原来的mask基础上Unblock signal set
SIG_SETMASK
设置mask为指定的signal set
2.
3.
12 sigpending Function
Sigpending函数返回当前被block而没有deliver的signal的集合:
#include <signal.h>
int sigpending(sigset_t *set);
成功返回0,错误返回-1
13 sigaction Function
sigaction用于修改或者获取某个signal所对应的action。Sigaction可以取代Signal函数,实际上,signal函数可以用sigaction函数来实现。。sigaction函数原型如下:
#include <signal.h>
int sigaction(int signo, const struct sigaction *restrict act, struct sigaction *restrict oact);
成功返回0,错误返回-1
1.
2.
3.
sigaction如下:
struct sigaction {
};
1.
2.
3.
Option
Description
SA_INTERRUPT
被该signal中断的系统调用不会自动重启
SA_NOCLDSTOP
如果signo是SIGCHLD,当子进程stop的时候不产生该signal
SA_NOCLDWAIT
如果signo是SIGCHLD,子进程不会变成zombie。当调用wait的时候,调用进程会一直等待直到所有子进程结束
SA_NODEFER
在signal处理函数中系统不会自动block该signal
SA_ONSTACK
如果调用了sigaltstack指定一个额外的stack,那么该signal发送的时候,进程处于此stack中
SA_RESETHAND
恢复为初始化值,SA_SIGINFO flag也会被清除
SA_RESTART
被该signal中断的系统调用会自动重启
SA_SIGINFO
为signal处理函数提供额外信息
4.
siginfo_t表示该signal为何产生:
struct siginfo_t {
};
而void *则应该被转换成ucontext_t结构,表示当signal产生时候的进程上下文信息
14 sigsetjmp and siglongjmp Functions
1.
2.
3.
#include <signal.h>
int sigsetjmp(sigjmp_buf env, int savemask);
直接调用返回0,从siglongjmp返回的时候返回非0
void siglongjmp(sigjmp_buf env, int val);
15 sigsuspend Function
Sigsuspend函数可以在一个原子操作内设置mask然后pause,防止设置mask之后pause之前,signal handler被调用,进程永远等待。原型如下:
#include <signal.h>
int sigsuspend(sigset_t *sig);
总是返回-1,errno设置为EINTR
16 abort Function
Abort函数等价于raise (SIGABRT)。注意就算是signal处理函数处理了SIGABRT,进程仍然会结束。
17 system Function
System函数除了会执行可执行文件创建子进程之外,还会设置sigmask为忽略SIGINT,SIGQUIT并Block SIGCHLD。
1.
2.
18 sleep Function
Sleep函数可以sleep某段时间,精确性无法保证。进程睡眠指定时间,直到时间到或者signal产生并被handler处理。注意sleep可能会由alarm函数实现,所以把alarm函数和sleep函数混着使用可能会造成无法预料的结果。
19 Job-Control Signals
SIGCHLD, SIGCONT, SIGSTOP, SITTSTP, SIGTTIN, SITTOU被认为是和Job Control有关的signal。大部分情况下,程序无需处理这些signal,除了SIGCHLD之外。
20 Additional Features
有些系统提供sys_siglist数组,保存着每个signal对应的字符串描述。
extern char *sys_siglist[];
很多系统提供psignal函数输出一个msg + ‘: ’ + signal string
#include <signal.h>
void psignal(int四个,const char *msg);
另一个常用函数是strsignal,返回signo对应的描述
#include <string.h>
char *strsignal(int signo);
返回对应的描述
Solaris提供把signal和名称对应起来的函数:
#include <string.h>
int *sig2str(int signo, char *str);
int str2sig(const char *str, int *signop);
返回对应的描述
Sig2str把signal转换为对应的描述字符串,而str2sig则是将描述字符串转换为signal。
- UNIX.signal
- UNIX.signal
- UNIX.signal详解
- Linux / Unix Command: signal
- The Unix Signal
- unix中的signal处理过程
- unix signal信号捕捉机制
- UNIX 编程之signal() 函数
- Unix下kill signal 号及其说明
- UNIX平台信号(SIGNAL)处理
- unix信号处理函数 signal (1)
- How to input "EOF" signal in unix?
- unix信号处理函数 signal (1)
- UNIX环境高级编程之-----信号signal
- unix like编程中的signal()函数
- [UNIX]signal函数捕捉SIGCLD信号
- Unix:signal调用类成员函数 / Linux:signal调用类成员函数
- 理解UNIX系统的signal函数的定义
- poj 3347 Kadj Squares(扩大数据运算的典型应用+映射)
- 【Linux 基础】入门知识
- 全中文版本:卡扎菲的遗嘱
- 统计你输入的任意字符
- error: 'FALSE' undeclared (first use in this function)
- UNIX.signal
- Spring 资源访问剖析和策略模式应用
- 卡扎菲治下利比亚人的福利
- 键盘输入变简单了
- I2S音频总线学习(三)S3C2440的I2S控制器
- 微软11月7日将举行Windows Phone大会
- RHCE 培训笔记(二) 文件系统
- 菜鸟不菜学习mvc(一)
- 关于多线程中的可重入函数问题