信号作为异步进程的通信方式,在实际应用中是方便而实用的。但是,也应该注意到在使用信号时的潜在危险。在此简单介绍几种可能引发错误的具体情况,希望在实际进行信号处理时特别注意。
当注册了一个信号处理函数时,可能会对某些系统调用进行修改。通常来讲,它们本来应是不受信号的影响,但由于注册了一个信号处理函数,系统可能会认为在一个信号到来时需要中断原系统调用。当这种情况发生时,原系统调用被终止,返回调用失败值,同时errno将被设置为EINTR。当然有一些时候,确实希望系统如此处理,但在另一些情况下,并不希望这样,因为有可能由于返回的错误代码使其后的进程无法按所希望的方向进行,甚至可能由于在后续的运行中未对出错返回作出相应处理而认为调用成功,从而导致数据的丢失。因此,建议使用函数sigaction 设置SA_RESTART 标志来防止这一情况的发生。
另一种情况是,在执行用户自行设置的信号处理函数时,也可能会有另一个信号产生。这时可能造成第一个调用被中断而进行第二个信号处理函数的调用。当第二个调用结束后再继续第一个调用的执行。这将会对函数的运行造成影响,特别是对使用了静态变量的程序。对这种情况,可以调用函数sigaction 设置SA_NODEFER 来阻塞第二个信号。
此外,在一个繁忙的系统中,对于涉及到系统时间的操作,可能会与预期的效果有所不同。例如在alarm 调用后调用了函数pause,希望在alarm 设定的报警发生时结束pause 状态。但由于系统过于繁忙而使此进程分到的时间片过少,当报警发生时,函数pause 还未被调用到,则当函数pause 被调用到时将可能造成进程被永远挂起。
-----(以上摘自《linux环境c编程指南》)