APUE学习笔记——10.可靠信号与不可靠信号

2022-11-20,,,

首先说明:现在大部分Unix系系统如Linux都已经实现可靠信号

1~31信号与SIGRTMIN-SIGRTMAX之间并不是可靠信号与不可靠信号的区别,在大多数系统下他们都是可靠信号。

只不过:

1~31信号           
               
  ——不支持排队,为普通信号。(不能用于统计信号发生次数的情景。)

SIGRTMIN-SIGRTMAX信号
——支持排队,实时信号

不可靠信号

什么是不可靠信号:

不可靠的意思是信号可能丢失或者被错误处理。

在早起系统中,信号存在两大缺陷,导致了信号不可靠。

缺陷一:

    信号发生后,信号处理方式被重置为系统默认动作。依旧是说,signal函数知识把信号和我们的信号处理函数关联一次,在发生一次信号后,信号的处理方式就被重置为系统默认了。

    这就导致了信号处理函数必须使用如下代码:

int  sig_int(); /* my signal handling function */
...
signal(SIGINT, sig_int); /* @1establish handler    */    
...
sig_int()
{
signal(SIGINT, sig_int); /* @2reestablish handler for next time */
...
./*process the signal ... */
...
}

    我们不得不在信号处理函数中再次使用signal()。

    但是,这样的处理并不能保证程序完全正确,因为在发生一次信号时,在我们开始调用sig_int函数,到执行sig_int函数中的signal函数(也就是我们@2代码)之间是有时间间隔的.如果在这段时间间隔里发生了再次发生了信号,那么针对这个信号的处理方式就是系统默认的方法了。

    所以早期的信号时不可靠的,因为他不能保证信号都使用正确的(我们期望的)处理方式进行处理。

缺陷二:

    信号对进程的控制能力差:

    早期系统实现中,当我们不希望信号发生时,进程无法关闭一个 信号,并在记录它的发生。

    很多时候我们有这样的需求,我们不希望信号打断某项的工作,但是当工作执行完后,又希望系统告诉我们这段时间内发生了什么信号。比如我们运行一段程序,要求运行完之前不能中断它(比如我们的Ctl+C),这是就需要暂时关闭这个信号。

    首先我们明确需求,我们需要的是,信号暂时不起作用,并在之后能够提醒我们信号发生过。

    为了实现这一点,我们使用下面代码

int  sig_int();     /* my signal handling function */
int  sig_int_flag; /* set nonzero when signal occurs */
main()
{
    signal(SIGINT, sig_int); /* establish handler */
    ...
    while (sig_int_flag == 0)
        pause();  /* go to sleep, waiting for signal */
    ...
}
sig_int()
{
    signal(SIGINT, sig_int); /* reestablish handler for next time */
    sig_int_flag = 1; /* set flag for main loop to examine */
}

    sig_int只有两行代码,它的作用就是忽略信号,并且用sig_int_flag标志信号发生过。

    之所以用while只因为pause可能会被其他信号中断。(我的理解)

    

    在这段代码中仍然有缺陷,在while测试后,pause之前有一段时间间隔, 在这段时间间隔里如果信号发生,并且此后不再发生,则进程会一直进入睡眠状态。

可靠信号:

    可靠信号针对解决不可靠信号的两点缺陷来理解:

解决不可靠信号缺陷一

    用sigaction代替signal

(在现代大多数系统中,signal也使用了sigaction实现,因此事可靠的。)建议尽可能使用sigaction替代signal,因为sigaction是同一的标准,可移植性强。

     一旦给信号被sigaction安装了一个动作,那么在sigaction调用显示改变它之前,这个信号动作将一直有效,也就是说不会执行一次就回复默认动作。这种处理方式不同于早期系统的信号不可靠的信号处理方式。可以说现在系统的信号处理方式是可靠的。

    关于sigaction与signal的更多介绍可参考本博相关博文。

解决不可靠信号缺陷二:

    用户可以通过sigprocmask、sigaction设置屏蔽字是信号阻塞。使信号处于pending状态,这样也就自然解决了缺陷二。

        

APUE学习笔记——10.可靠信号与不可靠信号的相关教程结束。

《APUE学习笔记——10.可靠信号与不可靠信号.doc》

下载本文的Word格式文档,以方便收藏与打印。