一、什么是Interrupted System Call
Interrupted system call 是指在系统调用(system call)过程中,收到来自外部世界的信号(signal)而中断所造成的返回值问题。
一般来说,系统调用会阻塞等待内核处理完指令再返回结果。如果在处理过程中被信号中断,执行流(execution flow)会跳转到信号处理函数(signal handler)处处理信号,直到处理完毕才又返回系统调用。这时候,如果不进行特殊的处理,系统调用的返回值便会变成 EINTR(Interrupted system call)。
二、为什么会发生Interrupted System Call
Interrupted system call 的发生与操作系统的信号处理机制有关系。当操作系统接收到一个信号时,会在执行流正在执行的上下文处使其转而执行信号处理函数,待处理完成后再返回原来的执行流。当处理器执行到系统调用时,若此时有信号到来,则会引起刚才所述的跳转,也就是Interrupted system call。常见的可以触发 Interrupted system call 的信号包括:SIGALRM、SIGINT、SIGKILL等。
三、如何处理Interrupted System Call
一些阻塞系统调用在 EINTR 返回值出现时会进行自动重启(automatic restart),而有些则不会。这导致了多种处理 Interrupted system call 的方法:
1.在 EINTR 发生时进行自动重启
fd_set readfds; int val = select(maxfd+1, &readfds, NULL, NULL, NULL); while(val == -1 && errno == EINTR) { val = select(maxfd+1, &readfds, NULL, NULL, NULL); }
2.使用 sigaction 设置系统调用信号处理程序,使得系统调用能够在被中断后重新执行而不产生 EINTR。
struct sigaction new_action, old_action; new_action.sa_handler = my_sigchld_handler; sigemptyset(&new_action.sa_mask); new_action.sa_flags = 0; sigaction(SIGINT, NULL, &old_action); if (old_action.sa_handler != SIG_IGN) sigaction(SIGINT, &new_action, NULL);
3.使用慢系统调用,如:accept、read、write等。这些系统调用可以保证在阻塞等待时收到信号不会造成 hard interrupt 的问题。例如:
ssize_t nbytes; while ((nbytes = read(fd, ptr, length)) == -1 && errno == EINTR) ;
四、Interrupted System Call的影响
在调用特定的系统调用时,如果没有正确处理 Interrupted system call,将会对程序的正确性和稳定性产生很大的影响。常见的表现会是程序不响应、程序死锁、资源泄漏等一系列问题。
举个例子:在使用 select 等待 I/O 事件的时候,如果不考虑 Interrupted System Call,可能会导致进程对 I/O 事件的失去响应,最终表现为网络套接字长时间不被读写,应用程序看似正常,但内部的连接等长时间处于未处理状态。
五、Interrupted System Call 发生的问题
出现 Interrupted System Call 的原因是操作系统接收到了一个信号。如果我们忽略 Interrupted System Call 带来的问题,可能会引起以下几个主要的问题:
1.防止无限期的等待
如果程序使用阻塞的 I/O,等待永远执行,程序就永远不会停止。这就是所谓的“无限期等待”问题。为了防止这种问题出现,需要在工作队列上进行特殊处理来检查 I/O 状态,以便正确处理 Interrupted System Call。
2.崩溃
由于 Interrupted System Call 引起的程序异常可能导致应用程序崩溃。这可能会产生一系列严重的问题,包括数据丢失和无法恢复的应用程序错误。
3.数据损坏
出现 Interrupted System Call 可能会导致数据损坏问题。由于传输过程中数据在进程和内核之间传递,如果进程在中断之前读取没完的数据,可能会导致数据的混乱,以至于无法正常处理。
六、小结
Interrupted System Call 是经常出现的问题,我们必须采取适当的措施来规避它。本文介绍了 Interrupted System Call 的原因和影响,以及如何处理它。通过合理的处理 Interrupted System Call 可以使程序更加健壮,提高系统的稳定性。
原创文章,作者:QGSIX,如若转载,请注明出处:https://www.506064.com/n/316223.html