设置信号处理方式
void (*signal(int signum,void(* handler)(int)))(int);
signal(int signum,void (*handler)(int));
signal的第一参数:
SIGHUP 1 发送给具有Terminal的Controlling Process,当terminal 被disconnect时候发送
SIGINT 2 由Interrupt Key产生,通常是CTRL+C或者DELETE。发送给所有ForeGround Group的进程
SIGQUIT 3 输入Quit Key的时候(CTRL+\)发送给所有Foreground Group的进程
SIGILL 4 非法指令异常
SIGTRAP 5 实现相关的硬件异常。一般是调试异常
SIGIOT 6 实现相关的硬件异常,一般对应SIGABRT
SIGABRT 6 由调用abort函数产生,进程非正常退出
SIGBUS 7 某种特定的硬件异常,通常由内存访问引起
SIGFPE 8 数学相关的异常,如被0除,浮点溢出,等等
SIGKILL 9 无法处理和忽略。中止某个进程
SIGUSR1 10 用户自定义signal 1
SIGSEGV 11 非法内存访问
SIGUSR2 12 用户自定义signal 2
SIGPIPE 13 在reader中止之后写Pipe的时候发送
SIGALRM 14 用alarm函数设置的timer超时或setitimer函数设置的interval timer超时
SIGTERM 15 请求中止进程,kill命令缺省发送
SIGSTKFLT 16 Linux专用,数学协处理器的栈异常
SIGCHLD 17 子进程终止
SIGCONT 18 当被stop的进程恢复运行的时候,自动发送
SIGSTOP 19 中止进程。无法处理和忽略。
SIGTSTP 20 Suspend Key,一般是Ctrl+Z。发送给所有Foreground Group的进程
SIGTTIN 21 当Background Group的进程尝试读取Terminal的时候发送
SIGTTOU 22 当Background Group的进程尝试写Terminal的时候发送
SIGURG 23 当out-of-band data接收的时候可能发送
SIGXCPU 24 当CPU时间限制超时的时候
SIGXFSZ 25 进程超过文件大小限制
SIGVTALRM 26 setitimer函数设置的Virtual Interval Timer超时的时候
SIGPROF 27 Setitimer指定的Profiling Interval Timer所产生
SIGWINCH 28 当Terminal的窗口大小改变的时候,发送给Foreground Group的所有进程
SIGIO 29 异步IO事件
SIGPOLL 29 当某个事件发送给Pollable Device的时候发送
SIGPWR 30 和系统相关。和UPS相关。
SIGSYS 31 非法系统调用
SIGRTMIN 32
SIGINFO BSD signal。由Status Key产生,通常是CTRL+T。发送给所有Foreground Group的进程
signal的第二个参数:
SIG_IGN 这个符号表示忽略该信号。
SIG_DFL 这个符号表示恢复对信号的系统默认处理
void(*func)(int) 为信号指定处理函数
int sigaction(int signo,const struct sigaction *act,struct sigaction* oldact);
signo 当触发此信号时,会进入act的信号处理函数
act 当act的信号处理函数执行期间,会屏蔽act.sa_mask信号
oldact 如果不是 NULL 指针,则原来的信号处理方式会由此结构 sigaction 返回
struct sigaction{
void (*sa_handler)(int); 信号处理函数
sigset_t sa_mask; 信号屏蔽集合
int sa_flag; 注(1):
void (*sa_sigaction)(int,siginfo_t*,void*); 替代的信号处理程序,当设置SA_SIGINFO时才会用他。
};
注1:
sa_flag: 默认为0
SA_NODEFER: 当信号处理函数正在进行时,不堵塞对于信号处理函数自身信号功能。
SA_RESETHAND:当用户注册的信号处理函数被执行过一次后,该信号的处理函数被设为系统默认的处理函数。
SA_SIGINFO: 提供附加信息,一个指向siginfo结构的指针以及一个指向进程上下文标识符的指针
typedef struct siginfo_t{
int si_signo; //信号编号
int si_errno; //如果为非零值则错误代码与之关联
int si_code; //说明进程如何接收信号以及从何处收到
pid_t si_pid; //发送者的进程ID
pid_t si_uid; //发送者的用户ID
int si_status; //适用于SIGCHLD,代表被终止进程的状态
clock_t si_utime; //适用于SIGCHLD,代表被终止进程所消耗的用户时间
clock_t si_stime; //适用于SIGCHLD,代表被终止进程所消耗系统的时间
sigval_t si_value;
int si_int;
void * si_ptr;
void* si_addr;
int si_band;
int si_fd;
};
typedef struct{
unsigned long int __val[16];
}sigset_t;
typedef struct {
int si_signo;
int si_errno;
int si_code;
union sigval si_value;
} siginfo
union sigval {
int sival_int;
void *sival_ptr;
}
信号屏蔽集合
sigemptyset(sigset_t *set);
函数说明:sigemptyset()用来将参数set 信号集初始化并清空.
返回值:执行成功则返回0, 如果有错误则返回-1.
int sigfillset(sigset_t *set);
把信号集初始化包含所有已定义的信号。
int sigaddset(sigset_t *set, int signo);
把信号signo添加到信号集set中,成功时返回0,失败时返回-1。
int sigdelset(sigset_t *set, int signo);
把信号signo从信号集set中删除,成功时返回0,失败时返回-1.
int sigismember(sigset_t *set, int signo);
该函数的作用是判断给定的信号signo是否是信号集中的一个成员
如果是返回1,如果不是,返回0,如果给定的信号无效,返回-1;
int sigpending(sigset_t *set);
该函数的作用是将被阻塞的信号中停留在待处理状态的一组信号写到参数set指向的信号集中
成功调用返回0,否则返回-1,并设置errno表明错误原因。
int sigsuspend(const sigset_t *sigmask);
该函数通过将进程的屏蔽字替换为由参数sigmask给出的信号集,然后挂起进程的执行。
注意操作的先后顺序,是先替换再挂起程序的执行。程序将在信号处理函数执行完毕后继续执行。
如果接收到信号终止了程序,sigsuspend()就不会返回,如果接收到的信号没有终止程序,sigsuspend()就返回-1,并将errno设置为EINTR。
int sigpromask(int how, const sigset_t *set, sigset_t *oset);
该函数可以根据参数指定的方法修改进程的信号屏蔽字。
新的信号屏蔽字由参数set(非空)指定,而原先的信号屏蔽字将保存在oset(非空)中。
如果set为空,则how没有意义,但此时调用该函数,如果oset不为空,则把当前信号屏蔽字保存到oset中。
how:
SIG_BLOCK 把参数set中的信号添加到信号屏蔽字中
SIG_SETMASK 把信号屏蔽字设置为参数set中的信号
SIG_UNBLOCK 从信号屏蔽字中删除参数set中的信号
如果sigpromask成功完成返回0,如果how取值无效返回-1,并设置errno为EINVAL。
注意:调用这个函数才能改变进程的屏蔽字,之前的函数都是为改变一个变量的值而已,并不会真正影响进程的屏蔽字。
信号的发送
定时器
unsigned int alarm(unsigned int seconds);
seconds:指定秒数
向系统发送SIGALRM信号
函数返回值:
成功:如果调用此alarm()前,进程已经设置了闹钟时间,则返回上一个闹钟时间的剩余时间,否则返回0。
出错:-1
extern __usconds_t ualarm(__useconds_t __value, __useconds_t __interval);
在使当前进程在指定时间(第一个参数)内产生SIGALRM信号,然后每隔指定时间(第二个参数)重复产生SIGALRM信号。
int setitimer(int which, const struct itimerval *new_value,struct itimerval *old_value);
int getitimer(int which, struct itimerval *value);
用来实现延时和定时的功能
which参数表示类型,可选的值有:
ITIMER_REAL: 以系统真实的时间来计算, 送出SIGALRM信号。
ITIMER_VIRTUAL: 以该进程在用户态下花费的时间来计算, 送出SIGVTALRM信号。
ITIMER_PROF: 以该进程在用户态下和内核态下所费的时间来计算, 送出SIGPROF信号。
new_value 用来对计时器进行设置
old_value 通常用不上,设置为NULL,它是用来存储上一次setitimer调用时设置的new_value值。
struct itimerval {
struct timeval it_interval; //计时器重启动的间歇值
struct timeval it_value; //计时器安装后首先启动的初始值
};
struct timeval {
long tv_sec; //秒
long tv_usec; // 微妙(1/1000000)
};
自举信号
int raise(int sig);
int kill(pid_t pid, int sig);
pid:可能选择有以下四种
pid大于零时,pid是信号欲送往的进程的标识。
pid等于零时,信号将送往所有与调用kill()的那个进程属同一个使用组的进程。
pid等于-1时,信号将送往所有调用进程有权给其发送信号的进程,除了进程1(init)。
pid小于-1时,信号将送往以-pid为组标识的进程。
int sigqueue(pid_t pid, int sig, const union sigval val)
pid 指定接收信号的进程ID
sig 即将发送的信号
val 信号传递的参数
sigqueue发送的数据由siginfo_t中的si_int或si_value来接收
等待信号
int pause(void);
描述:
pause() 库函数使调用进程(或线程)睡眠状态,直到接收到信号,要么终止,或导致它调用一个信号捕获函数
返回值:
pause()函数仅在捕获信号并返回信号捕获功能时返回。
在这种情况下,PAUSER()返回-1,errno设置为EINTR