14-重入
10.4 重入
当内核发送信号时,进程可能执行到代码中的任何位置。例如,进程可能正执行一个重要的操作,如果被中断,进程将会处于不一致状态(例如数据结构只更新了一半,或计算只执行了一部分)。进程甚至可能正在处理另一个信号。
当信号到达时,信号处理程序不能说明进程正在执行什么代码,处理程序可以在任何情况下运行。因此任何该进程设置的信号处理程序都应该谨慎对待它的操作和它涉及的数据。信号处理程序必须注意,不要对进程中断时可能正在执行的操作做任何假设,尤其是当修改全局(也就是共享的)数据时,必须要慎重。确实,不让信号处理程序接触全局数据是一个比较好的选择。在接下来的部分,我们会看一种临时阻止接收信号的方法,从而提供一种处理信号处理程序和进程其他部分共享数据的安全操作方法。
系统调用和其他库函数又是什么情况呢?如果进程正在写文件或申请内存时,信号处理程序向同一个文件写入或也在调用malloc(),进程会如何处理?或者当信号被发送时,进程正在调用一个使用静态缓存的函数,例如strsignal(),又会发生什么情况?
一些函数显然是不可重入的。如果程序正在执行一个不可重入的函数时,信号发生了,信号处理程序调用同样的不可重入函数,那么就会造成混乱。可重入函数是指可以安全地自我调用(或者从同一个进程的另一个线程)的函数。为了使函数可重入,函数绝不能操作静态数据,必须只操作栈分配的数据或调用者提供的数据,并且不得调用任何不可重入的函数。