信号机制

1 信号的概念 

信号是软件中断,由系统内核产生;

不可靠信号 : 指 信号可能会被丢失——一个信号发生了,但进程却决不会知道这一点;

可靠信号相关术语 :  信号产生(硬件异常或软件条件等),信号传送(内核在相关进程表置上标志),信号在两者之间称为信号未决,进程可以选用“信号递送阻塞”。如果为进程产生了一个选择为阻塞的信号,而且对该信号的动作是系统默认动作或捕捉该信号,则该信号处于未决状态,当处于未决状态的信号有多个时,Unix下一般在解除该信号阻塞后在信号处理函数中只处理一次;

SIGINT: 中断信号               SIGSEGV:存储访问出错     SIGQUIT: 退出信号       SIGCHLD: 子进程中止信号

系统对信号的基本操作:(三种)

1)忽略该信号;(SIGKILL和SIGSTOP信号不能忽略,这是超级用户杀死进程的有效方法)

2)捕捉该信号;

3)默认操作

2 信号函数

#define SIG_ERR (void (*)())-1
#define SIG_DFL (void (*)())0
#define SIG_IGN (void (*)())1

 #include <signal.h>

 typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler);

alarm(int nsec); 超时函数,超时产生一个SIGALRM信号

pause();挂起当前进程,直到信号处理函数返回;

信号集相关函数

int sigemptyset(sigset_st e t)* ;
int sigfillset(sigset_st e t)* ;
int sigaddset(sigset_ts e t,* int s i g n o) ;
int sigdelset(sigset_ts e t,* int s i g n o) ;
上面四个函数返回:若成功则为0,若出错则为-1
int sigismember(const sigset_s et t, *int s i g n o)

int sigprocmask(inht o w, const sigset_ts e *t, sigset_t o* s e t) ;
返回:若成功则为0,若出错则为-1

h o w 说明
S I G _ B L O C K :该该进程新的信号屏蔽字是其当前信号屏蔽字和s e t指向信号集的并集。s e t包含了我们希望阻塞的附加信号
S I G _ U N B L O C K: 该该进程新的信号屏蔽字是其当前信号屏蔽字和s e t所指向信号集的交集。s e t包含了我们希望解除阻塞的信号
S I G _ S E T M A S K 该该进程新的信号屏蔽是s e t指向的值如果s e t是个空指针,则不改变该进程的信号屏蔽字, h o w的值也无意义。


注意:如果在调用s i g p r o c m a s k后有任何未决的、不再阻塞的信号,则在s i g p r o c m a s k返回前,至少将其中之一递送给该进程。(相当解阻塞即时生效)

int sigpending(sigset_st e t)* ; 返回对于调用进程被阻塞不能递送和当前未决的信号集。该信号集通过s e t参数返回。

int sigaction(int signo, const struct sigactioan *act,struct sigactiono *oldact) ;
struct sigaction {
    void (*sa_handler)(); /* addr of signal handler,or SIG_IGN, or SIG_DFL */
    sigset_t sa_mask; /* additional signals to block */     
    int sa_flags; /* signal options, Table 10-5 */
} ;

int sigsuspend(const sigset_st * mask) ;

返回:-1, errno设置为E I N T R

该函数用在设置暂时信号屏蔽字,在该函数返回后(条件是捕捉处理完信号),屏蔽字恢复先前值;

下面是一段使用该函数的例子,用来保护某段关键代码不受SIGINT信号影响;

sigset newmask,oldmask,zeromask;

if(signal(SIGINT,sig_int) == SIG_ERR)

   err_sys("signal(SIGINT) error");

sigemptyset(&newmask);sigempty(&zeromask);

sigaddset(&newmask,SIGINT);

sigprocmask(SIG_BLOCK,&newmask,&oldmask);

/*critical region of  code*/

.......

/* 恢复进程老的屏蔽字,若不这样作,阻塞的SIGINT可能会给进程带来额外操作*/

sigsuspend(&zeromask);

sigprocmask(SIG_SETMASK,&lodmask,NULL);

exit(0);

你可能感兴趣的:(信号机制)