http://blog.csdn.net/dianhuiren/article/details/7291540(博客不错)
慢系统调用和其他两大类别。
以下几个类别:
(1)读写‘慢’设备(包括pipe,终端设备,网络连接等)。读时,数据不存在,需要等待;写时,缓冲区满或其他原因,需要等待。读写磁盘文件一般不会阻塞。
(2)当打开某些特殊文件时,需要等待某些条件,才能打开。例如:打开中断设备时,需要等到连接设备的modem响应才能完成。
(3)pause和wait函数。pause函数使调用进程睡眠,直到捕获到一个信号。wait等待子进程终止。
(4)某些ioctl操作。
(5)某些IPC操作。
信号中断,还是要继续执行该操作,即需要重启该操作。那么,程序需要检查系统调用的错误类型是否为EINTR,如果是,表明系统调用被中断,则重新启动操作。典型代码如下所示:
again:
if ((n = read(fd, buf, BUFFSIZE)) < 0) {
if (errno == EINTR)
goto again; /* just an interrupted system call */
/* handle other errors */
}
4.2BSD为了简化程序的操作,提供了自动重启某些被中断系统调用的功能,这些系统调用包括ioctl,read,readv,write,writev,wait,waitpid。前五个函数当它们操作慢设备时,才会被中断。这可能给那些不希望自动重启这些系统调用的应用带来麻烦,所以4.3BSD允许进程在指定信号上关闭此功能。
POSIX.1允许实现重新启动系统调用,但没有强制要求。SUS给sigaction增加了一个XSI扩展标记SA_RESTART,要求被该信号中断的系统调用被自动重启。
一般慢速系统调用基本规则是:当阻塞于某个慢系统系统调用的一个进程捕获某个信号且相应信号处理函数返回时,该系统调用可能要返回
ENINTR错误。
问:linux会重启某些被中断的系统调用吗?
处理的例子:
}
}
在tcp socket 中,connect()被中断后是不能被重启的?如何处理呢
可以采用select来等待连接完成
系统调用被信号中断和自动重启动
return;
}
在我的系统中, 如果调用默认的signal函数, 该read()系统调用将会自动重启动, 所谓的alarm定时也就不起作用了。