linux网络编程---慢系统调用和中断信号EINTR

时间:2021-03-11 14:46:28
      我们用慢系统调用来描述那些可能永远堵塞的系统调用(函数调用),如:accept,read等。永远堵塞的系统调用是指调用有可能永远无法返回,多数网络支持函数都属于这一类。例如,如果没有客户连接到服务器上,则服务器对accept的调用就没有返回保证。类似的,如果客户从未发送过一行要求服务器回射的文本,则服务器对read的调用将永不返回。

      当一个进程阻塞在一个慢系统调用函数的时候,捕获到一个信号,等到信号处理程序返回时,该慢系统调用函数可能返回一个EINTR错误。有些内核自动重启某些被中断的系统调用。为了便于移植,当我们编写一个捕获信号的程序时(多数并发服务器捕获SIGCHLD),我们必须对慢系统调用返回EINTR有所准备。

如下为一个对accept函数的处理例子:

for( ; ; )
{
clien=sizeof(cliaddr);
if((connfd=accept(listenfd,(SA*)&cliaddr,&clien))<0)
{
if(errno==EINTR)
continue;
else
err_sys("accept error");
}
}
在这段代码中,我们所做的就是自己重启被中断的系统调用,这对于accept以及其他诸如read,write,select和open这样的函数是合适的。
       但有一个函数我们不能自己重启:connect。如果这个函数返回INTER,我们就不能再调用它,否则返回错误。当connect失败则该套接字不可再用,必须关闭close(sd),我们不能对这样的套接字再次调用connect函数。必须重新调用socket()函数获得新的套接字。