分类:
2008-12-08 11:42:51
10.5 interrupted system calls
一个signal handler可以在一个函数的两条语句之间被调用,即signal可以在一个函数内部截断原函数的执行,当handler 执行完毕后,再次回到原函数,这要保证你这个函数是可重入的话才会安全。一般来说对全局数据进行访问的函数都不敢保证是可重入的。还有一种情况,当你的函数在执行一些slow的调用时,比如block在某个函数时,当一个signal发生,signal handler被调用后,以前那个被block的函数调用就被interrupted了。其接下来的处理,有几种情况:
1.让这个block函数返回失败,error设置为EINTR,这是老的unix的做法
2.让这个block函数返回成功,不过返回值表明了他只是成功了一部分,比如read, write的真正的读取和写入的数据量并不等于原本要处理的数据量。
3.并不让其返回,而是直接将其restart。这是后来出现的一种机制,这是有好处的,最起码可以避免上端应用 频繁的在每个read/write调用处检查是否被interrupte了,因为就算你被interrupte了你也会被restart, 那么你只要返回了要么就是直接工作完了,要么就是被interrupt之后又restart了最后工作完了。
下面就是一段繁琐的检查系统调用是否被interrupte的代码:
again:
if ((n = read(fd, buf, BUFFSIZE)) < 0) {
if (errno == EINTR)
goto again; /* just an interrupted system call */
/* handle other errors */
}
当然,并不是所有的情况下用户都想让他的系统调用自动restart, 还是可以控制的好。
下面是一个图,它描述了各个不同的unix implementation针对signal机制的是否支持signal handler的自动re-install, 系统调用在被interrupted后是否会自动restart,是否支持block某些signal.:
Figure 10.3. Features provided by various signal
implementations |
||||
Functions |
System |
Signal handler remains installed |
Ability to block signals |
Automatic restart of interrupted system calls? |
signal |
ISO C, POSIX.1 |
unspecified |
unspecified |
unspecified |
V7, SVR2, SVR3, SVR4, Solaris |
|
|
never |
|
4.2BSD |
• |
• |
always |
|
4.3BSD, 4.4BSD, FreeBSD, Linux, Mac OS X |
• |
• |
default |
|
sigset |
XSI |
• |
• |
unspecified |
SVR3, SVR4, Linux, Solaris |
• |
• |
never |
|
sigvec |
4.2BSD |
• |
• |
always |
4.3BSD, 4.4BSD, FreeBSD, Mac OS X |
• |
• |
default |
|
sigaction |
POSIX.1 |
• |
• |
unspecified |
XSI, 4.4BSD, SVR4, FreeBSD, Mac OS X, Linux, Solaris |
• |
• |
optional |
基本上,上述函数,只有signal和sigaction被使用,其他的都过时了。
所谓slow的系统调用,有如下几种情况:
1.Reads that can block the caller forever if data isn't present with certain file types (pipes, terminal devices, and network devices) 读取pipe, terminal device, network
2.Writes that can block the caller forever if the data can't be accepted immediately by these same file types, 对pipe,terminal device, network的写操作
3.Opens that block until some condition occurs on certain file types (such as an open of a terminal device that waits until an attached modem answers the phone) 打开一个terminal device
4.The pause function (which by definition puts the calling process to sleep until a signal is caught) and the wait function
5.Certain ioctl operations
6.Some of the interprocess communication functions ()
注意,对disk的i/o相关的操作,并不包括在上述之内,因为对disk的读写操作虽然也会block,但被认为是肯定要返回的操作,除非是因为disk i/o错误,才会返回错误,而不可能因为被interrupted而返回错误。