刘敬贤大师徒弟名单:不可靠信号与可靠信号对比

来源:百度文库 编辑:中财网 时间:2024/04/28 06:04:22

早期版本不可靠信号

一个缺陷是:每当信号发生时,信号的处理被系统设置为默认的设置。


Oneproblem with these early versions is that the action for a signal was reset toits default each time the signal occurred.

Theclassic example from programming books that described these earlier systemsconcerns how to handle the interrupt signal. The code that was describedusually looked like

         int    sig_int();        /* my signalhandling function */

 

         ...

         signal(SIGINT, sig_int);  /* establish handler */

         ...

 

    sig_int()

    {

         signal(SIGINT, sig_int);  /* reestablishhandler for next time,体现了上面所说 */

         ...                       /* process the signal... */

    }

信号发生信号处理函数中调用signal重新设置之间存在一个时间窗,在这个时间窗里信号是的执行默认动作(有可能是退出程序)或者被忽略(相当于这个信号丢失)。

另外一个缺陷是:进程对信号的控制能力很差

用户无法通知内核阻塞一个信号(不要忽略该信号),在其发生的时候记住它,然后当进程做好准备时,再让内核通知信号。

Another problem with these earlier systems is that the processwas unable to turn a signal off when it didn't want the signal to occur. Allthe process could do was ignore the signal. There are times when we would liketo tell the system "prevent the following signals from occurring, butremember if they do occur." The classic example that demonstrates thisflaw is shown by a piece of code that catches a signal and sets a flag for theprocess that indicates that the signal occurred:

     int     sig_int_flag;         /* set nonzero when signal occurs */

 

     main()

     {

          int      sig_int();       /* my signal handling function */

          ...

          signal(SIGINT, sig_int);  /* establish handler */

          ...

          while (sig_int_flag == 0) /*为什么要判断,这样可以确认是执行了sig_int,执行了SIGINT的信号处理函数;为什么不使用if,既然pause直到捕捉到一次信号才返回,并且肯定只会执行一次?,看下文*/

             pause();              /* go to sleep, waiting forsignal */

          ...

     }

 

     sig_int()

     {

          signal(SIGINT, sig_int);  /* reestablish handler for next time */

          sig_int_flag = 1;         /* set flag for main loop to examine*/

     }

在while (sig_int_flag == 0)和pause之间存在一个时间窗,在这个时间窗里如果信号发生,并且sig_int_flag = 1;  被执行过,后续没有新的信号到来,则进程一直pause(注意有三个条件);如果后续来了信号,也就不会一直pause,相当于一次信号的处理的结果(sig_int_flag = 1)丢失了。这也是之前用while比if好的地方,if的话如果丢失就必然一直pause。

可靠信号

针对缺陷一:Sigaction取代signal:

     structsigaction {

       void     (*sa_handler)(int);   /* addr ofsignal handler, */

                                       /* orSIG_IGN, or SIG_DFL */

       sigset_t sa_mask;               /* additional signals to block*/

       int     sa_flags;              /* signaloptions, Figure 10.16 */

 

       /* alternate handler */

       void    (*sa_sigaction)(int, siginfo_t *, void *);

   };

 

int sigaction(int signo,const struct sigaction *restrictact, struct sigaction *restrict oact);

 

设置的sa_mask字段被Sigaction“信号处理函数”前设置(类似sigprocmask设置信号屏蔽字);sigpending查询后执行该“信号处理函数”。

从调用Sigaction后到“信号处理函数”执行结束的这段时间,sa_mask字段和操作系统会保证被处理的信号一直被block.如果有信号,会再次执行“信号处理函数”。当然,由于信号的不排队,多次信号只会触发一次“信号处理函数”的执行。

Whenchanging the action for a signal, if the sa_handler field contains the address of asignal-catching function (as opposed to the constants SIG_IGN or SIG_DFL), then the sa_mask field specifies a set of signals that are added tothe signal mask of the process before the signal-catching function is called. If and when the signal-catchingfunction returns, the signal mask of the process is reset to its previousvalue.

This way, we are able to block certain signals whenever asignal handler is invoked. The operating systemincludes the signal being delivered in the signal mask when the handler isinvoked. Hence, we are guaranteed that whenever we are processing agiven signal, another occurrence of that same signal is blocked until we'refinished processing the first occurrence Recall from Section10.8 that additional occurrences of the same signal are usually notqueued. If the signal occurs five times while it is blocked, when we unblockthe signal, the signal-handling function for that signal will usually beinvoked only one time.

Once we install an action for a givensignal, that action remains installed until we explicitly change it by calling sigaction. Unlike earlier systems with their unreliable signals, POSIX.1 requiresthat a signal handler remain installed until explicitly changed.

 

针对缺陷二:增强了对信号的控制:

用户可以通知内核阻塞(block,通过sigprocmask或者Sigaction设置的信号屏蔽字)一个信号,在其发生的时候记住它(此时信号处于pending状态),然后当进程做好准备时,再获取处于pending状态的信号(通过sigpending)。

We say thata signal is delivered to a process when theaction for a signal is taken. During the time between the generation of asignal and its delivery, the signal is said to be pending.

A process has the option of blockingthe delivery of a signal. If a signal that is blocked is generated for aprocess, and if the action for that signal is either the default action or to catch the signal, thenthe signal remains pending for the process until the process either (a) unblocksthe signal or (b) changes the action to ignore the signal. The systemdetermines what to do with a blocked signal when the signal is delivered, notwhen it's generated. This allows the process to change the action for thesignal before it's delivered. The sigpending function (Section10.13) can be called by a process to determine which signals are blockedand pending.

PS:

基本上是对APUE的复制只是加了一点点理解,这里只是希望把对比给突出出来,当然这种生硬的分类对比未必恰当。如果希望更详尽系统的理解请看原书。

欢迎指教,欢迎拍砖,谢谢!